package com.meida.module.arc.provider.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.meida.common.base.entity.EntityMap;
import com.meida.common.base.utils.FlymeUtils;
import com.meida.common.mybatis.base.service.impl.BaseServiceImpl;
import com.meida.common.mybatis.model.ResultBody;
import com.meida.common.mybatis.query.CriteriaDelete;
import com.meida.common.mybatis.query.CriteriaQuery;
import com.meida.common.mybatis.query.CriteriaSave;
import com.meida.common.mybatis.query.CriteriaUpdate;
import com.meida.common.security.OpenHelper;
import com.meida.common.utils.ApiAssert;
import com.meida.common.utils.JsonUtils;
import com.meida.common.utils.ReflectionUtils;
import com.meida.module.arc.client.entity.*;
import com.meida.module.arc.client.enums.*;
import com.meida.module.arc.client.es.ArcOriginalEs;
import com.meida.module.arc.client.utils.ArcUtils;
import com.meida.module.arc.client.vo.ArcNumFmt;
import com.meida.module.arc.client.vo.ForEachIndex;
import com.meida.module.arc.provider.mapper.ArcInfoMapper;
import com.meida.module.arc.provider.repository.ArcOriginalRepository;
import com.meida.module.arc.provider.service.*;
import com.meida.module.system.client.entity.SysCompany;
import com.meida.module.system.client.entity.SysDept;
import com.meida.module.system.provider.service.SysCompanyService;
import com.meida.module.system.provider.service.SysDeptService;
import org.dromara.easyes.core.biz.EsPageInfo;
import org.dromara.easyes.core.conditions.select.LambdaEsQueryWrapper;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.util.*;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

/**
 * 档案信息表接口实现类
 *
 * @author flyme
 * @date 2021-12-05
 */
@Service
@Transactional(rollbackFor = Exception.class)
@DS("sharding")
public class ArcInfoServiceImpl extends BaseServiceImpl<ArcInfoMapper, ArcInfo> implements ArcInfoService {
    @Autowired
    private ArcCategorySuffixService arcCategorySuffixService;

    @Autowired
    private ArcFieldService arcFieldService;

    @Autowired
    private ArcCategoryService arcCategoryService;

    @Autowired
    private ArcConfigService arcConfigService;

    @Autowired
    private ArcConfigRefService arcConfigRefService;

    @Autowired
    private ArcOriginalService arcOriginalService;

    @Autowired
    private ArcStoreRoomService arcStoreRoomService;

    @Autowired
    private ArcCompilationRefService arcCompilationRefService;

    @Autowired
    private ArcCompilationCategoryService arcCompilationCategoryService;

    @Autowired
    private ArcUseService arcUseService;

    @Autowired
    private ArcDestoryService arcDestoryService;

    @Autowired
    private UserUnitService userUnitService;

    @Autowired
    private ArcCategorySecondService arcCategorySecondService;

    @Autowired
    private ArcSecondFieldService arcSecondFieldService;

    @Autowired
    private SyncServiceImpl syncService;
    @Value("${spring.datasource.dynamic.datasource.master.url:mysql}")
    private String dataSourceUrl;

    @Resource
    private DynamicDataSourceProperties dynamicDataSourceProperties;

    @Autowired
    @Lazy
    private ArcRefRecordService arcRefRecordService;

    @Autowired
    @Lazy
    private ArcDictService arcDictService;

    @Autowired
    @Lazy
    private SysDeptService sysDeptService;

    @Autowired
    @Lazy
    private SysCompanyService sysCompanyService;

    @Autowired
    ArcInfoCollectService arcInfoCollectService;

    @Resource
    private ArcOriginalRepository arcOriginalRepository;

    @Autowired
    private ArcUseRemindService arcUseRemindService;


    @Override
    public ResultBody beforeEdit(CriteriaUpdate<ArcInfo> cu, ArcInfo t, EntityMap extra) {
        ApiAssert.isNotEmpty("编辑档案id不能为空", t.getArcInfoId());
        ApiAssert.isNotEmpty("编辑档案门类id不能为空", t.getCategoryId());

        ArcInfo beforeEditObj = this.getArcInfo(t.getArcInfoId(), t.getCategoryId());


        ApiAssert.isNotEmpty("编辑档案不能为空", beforeEditObj);
        String beforeExpandStr = beforeEditObj.getExpand();

        Map beforeExpandMap = new EntityMap();
        if (FlymeUtils.isNotEmpty(beforeEditObj)) {
            //beforeExpandMap.putAll(JsonUtils.jsonToEntityMap(beforeExpandStr));
        }


        Field[] declaredFields = ArcInfo.class.getDeclaredFields();
        List<String> fieldsName = Arrays.stream(declaredFields).map(item -> {
            return item.getName();
        }).collect(Collectors.toList());
        EntityMap updateParam = cu.getRequestMap();

        updateParam.forEach((key, value) -> {
            if (!fieldsName.contains(key)) {
                beforeExpandMap.put(key, value);
            }
        });

        if (FlymeUtils.isNotEmpty(beforeExpandMap)) {
            t.setExpand(JsonUtils.beanToJson(beforeExpandMap));
        }
        cu.lambda().eq(ArcInfo::getCategoryId, t.getCategoryId());
        //校验重复
        checkArcInfoFiledNoRepeat(t.getCategoryId(), updateParam, t.getArcInfoId());

        //编辑档案后管理更新单位数据
        if (!beforeEditObj.getUnitId().equals(t.getUnitId())) {
            SysDept sysDept = sysDeptService.getById(t.getUnitId());
            sysDeptService.update(new UpdateWrapper<SysDept>().lambda().eq(SysDept::getDeptId, sysDept.getDeptId()).set(SysDept::getArcInfoCount, sysDept.getArcInfoCount() + 1));

            SysDept sysDeptOld = sysDeptService.getById(beforeEditObj.getUnitId());
            sysDeptService.update(new UpdateWrapper<SysDept>().lambda().eq(SysDept::getDeptId, sysDeptOld.getDeptId()).set(SysDept::getArcInfoCount, sysDeptOld.getArcInfoCount() - 1));
        }


        return ResultBody.ok();
    }

    @Override
    public ResultBody beforeGet(CriteriaQuery<ArcInfo> cq, ArcInfo t, EntityMap requestMap) {
        ApiAssert.isNotEmpty("门类id不能为空", t);
        ApiAssert.isNotEmpty("门类id不能为空", t.getCategoryId());
        requestMap.put("notFilterUnitId", 1);
        genArcInfoQuery(cq, t, requestMap);
        return ResultBody.ok();
    }

    @Override
    public void afterGet(CriteriaQuery cq, EntityMap result) {
        if (FlymeUtils.isNotEmpty(result)) {
            String expand = result.get("expand");
            if (FlymeUtils.isNotEmpty(expand)) {
                EntityMap map = JsonUtils.jsonToEntityMap(expand);
                result.putAll(map);
            }
        }
        //去除 expand字段
        result.remove("expand");
    }

    /**
     * 档案添加/修改校验值重复
     *
     * @param categoryId
     * @param map
     * @param exclusionArcInfoId 编辑时候要取消已有字段校验
     */
    private void checkArcInfoFiledNoRepeat(Long categoryId, EntityMap map, Long exclusionArcInfoId) {
        //1基于categoryId查询所有字段配置
        List<ArcField> fields = this.arcFieldService.listByCategoryId(categoryId);
        Map<String, ArcField> fieldsMap = fields.stream().collect(Collectors.toMap(ArcField::getFieldName, ArcField -> ArcField, (a, b) -> a));
        //2如果有
        map.forEach((key, value) -> {
            //如果字段配置有不重复则校验表中数据
            if (FlymeUtils.isNotEmpty(value) && fieldsMap.containsKey(key) &&
                    ArchiveEnumInteger.IS_TRUE.getCode().equals(fieldsMap.get(key).getInNoRepeat())) {
                ArcField field = fieldsMap.get(key);
                CriteriaQuery<ArcInfo> query = new CriteriaQuery<ArcInfo>(ArcInfo.class);
                query.lambda().eq(ArcInfo::getCategoryId, categoryId);
                if (ArchiveEnumInteger.IS_TRUE.getCode().equals(field.getIsBlob())) {
                    //query.eq("expand ->'$."+key+"'",value.toString());
                    query.eq(getExpandColumn(key), value.toString());
                } else {
                    //非扩展字段查询
                    if (field.getDataType().intValue() == 2) {//数字
                        query.eq(key, Integer.parseInt(value.toString()));
                    } else {//文本
                        query.eq(key, value.toString());
                    }
                }
                if (FlymeUtils.isNotEmpty(exclusionArcInfoId)) {
                    query.lambda().ne(ArcInfo::getArcInfoId, exclusionArcInfoId);
                }
                Long count = this.count(query);
                if (count > 0) {
                    ApiAssert.failure(String.format("[%s]字段值[%s]重复，无法保存", field.getFieldCnName(), value));
                }
            }
        });
    }

    @Override
    public ResultBody beforeAdd(CriteriaSave cs, ArcInfo info, EntityMap extra) {
        ApiAssert.isNotEmpty("档案信息不能为空", info);
        ApiAssert.isNotEmpty("档案门类id不能为空", info.getCategoryId());
        Field[] declaredFields = ArcInfo.class.getDeclaredFields();
        List<String> fieldsName = Arrays.stream(declaredFields).map(item -> {
            return item.getName();
        }).collect(Collectors.toList());
        EntityMap saveParam = cs.getRequestMap();
        Map expandMap = new HashMap();
        saveParam.forEach((key, value) -> {
            if (!fieldsName.contains(key) && FlymeUtils.isNotEmpty(value)) {
                expandMap.put(key, value.toString());
            }
        });
        if (FlymeUtils.isNotEmpty(saveParam)) {
            info.setExpand(JsonUtils.beanToJson(expandMap));
        } else {
            info.setExpand("");
        }
        //校验全局唯一
        checkArcInfoFiledNoRepeat(info.getCategoryId(), saveParam, null);
        //原文数量默认0
        info.setOriginalCount(0);
        return ResultBody.ok();
    }

    @Override
    public ResultBody afterAdd(CriteriaSave cs, ArcInfo t, EntityMap extra) {
        //新增档案后管理更新单位数据
        SysDept sysDept = sysDeptService.getById(t.getUnitId());
        SysCompany sysCompany = sysCompanyService.getById(t.getQzId());
        sysDeptService.update(new UpdateWrapper<SysDept>().lambda().eq(SysDept::getDeptId, sysDept.getDeptId()).set(SysDept::getArcInfoCount, sysDept.getArcInfoCount() + 1));
        sysCompanyService.update(new UpdateWrapper<SysCompany>().lambda().eq(SysCompany::getCompanyId, sysCompany.getCompanyId()).set(SysCompany::getArcInfoCount, sysCompany.getArcInfoCount() + 1));

        //判断是否关联父级
        Object parentArcInfoId = cs.getParams("parentArcInfoId");
        if (ObjectUtil.isNotNull(parentArcInfoId)) {
            Map map = new HashMap();
            map.put("parentArcInfoId", cs.getParams("parentArcInfoId"));
            map.put("parentCategoryId", cs.getParams("parentCategoryId"));
            map.put("type", "1");
            map.put("childCategoryId", t.getCategoryId());
            map.put("childArcInfoIds", t.getArcInfoId());
            batchInOrOut(map);
        }
        return ResultBody.ok("保存成功", t);
    }

    private void genArcInfoQuery(CriteriaQuery<ArcInfo> cq, ArcInfo info, EntityMap requestMap) {
        ApiAssert.isNotEmpty("参数不能为空", info);
        ApiAssert.isNotEmpty("门类id不能为空", info.getCategoryId());
        //0 查询所有字段
        cq.lambda().eq(ArcInfo::getCategoryId, info.getCategoryId());
        cq.addSelect("info.*");
        cq.eq("categoryId", info.getCategoryId());
        //1 查询门类所有可查询的字段
        List<ArcField> fields = this.arcFieldService.listByCategoryId(info.getCategoryId());
        //添加默认查询结果
        List<String> fieldsName = fields.stream().map(item -> {
            return item.getFieldName();
        }).collect(Collectors.toList());
        Map<String, ArcField> fieldMap = fields.stream()
                .collect(Collectors.toMap(ArcField::getFieldName, ArcField -> ArcField));
        //2 如果为为非扩展字段则通过字段查询  扩展字段基于json查询
        requestMap.forEach((key, value) -> {
            String tempKey = null;
            Boolean isNotBetween = true;
            boolean isEq = false;
            Integer tempType = 1;//1begin 2 end
            if (key.indexOf("Begin") > -1) {
                tempKey = key.replace("Begin", "");
                isNotBetween = false;
            } else if (key.indexOf("End") > -1) {
                tempType = 2;
                tempKey = key.replace("End", "");
                isNotBetween = false;
            } else {
                tempKey = key;
            }

            if (key.endsWith("_EQ_")) {
                tempKey = key.replace("_EQ_", "");
                isEq = true;
            }
            if (FlymeUtils.isNotEmpty(value)) {
                //非field表配置表
                Field[] declaredFields = ArcInfo.class.getDeclaredFields();
                Map<String, Field> declaredFieldMap = Arrays.stream(declaredFields).collect(Collectors.toMap(Field::getName, Field -> Field));
                boolean isLong = false;
                //Long型字段处理
                if (declaredFieldMap.containsKey(tempKey) && declaredFieldMap.get(tempKey).getType().getSimpleName().equals("Long")) {
                    isLong = true;
                }
                if (fieldsName.contains(tempKey)) {
                    ArcField obj = fieldMap.get(tempKey);
                    //扩展字段查询
                    if (ArchiveEnumInteger.IS_TRUE.getCode().equals(obj.getIsBlob())) {
                        if (isNotBetween) {
                            if (obj.getDataType() == 2) {//数字
                                //"json_extract(expand,\"$." + obj.getFieldName() + "\")"
                                cq.eq(getExpandColumn(obj.getFieldName()), requestMap.get(key));
                            } else {//文本
                                if (isEq) {
                                    cq.eq(getExpandColumn(obj.getFieldName()), requestMap.get(key));
                                } else {
                                    cq.like(getExpandColumn(obj.getFieldName()), requestMap.get(key));
                                }

                            }
                        } else {
                            if (tempType == 1) {
                                //大于等于
                                cq.ge(getExpandColumn(obj.getFieldName()), requestMap.get(key));
                            } else {
                                //小于等于
                                cq.le(getExpandColumn(obj.getFieldName()), requestMap.get(key));
                            }
                        }
                    } else {
                        if (isNotBetween) {
                            //非扩展字段查询
                            if (obj.getDataType() == 2) {//数字
                                if (!"originalCount".equals(obj.getFieldName())) {
                                    cq.eq(obj.getFieldName(), changeFieldValueType(isLong ? "Long" : "Integer", requestMap.get(key)));
                                }
                            } else {//文本
                                if (isEq) {
                                    if (!"originalCount".equals(obj.getFieldName())) {
                                        cq.eq(obj.getFieldName(), requestMap.get(key));
                                    }
                                } else {
                                    cq.like(obj.getFieldName(), requestMap.get(key));
                                }
                            }
                        } else {
                            if (tempType == 1) {
                                //大于等于
                                cq.ge(obj.getFieldName(), requestMap.get(key));
                            } else {
                                //小于等于
                                cq.le(obj.getFieldName(), requestMap.get(key));
                            }
                        }
                    }
                } else {
                    //系统字段查询
                    if (declaredFieldMap.containsKey(tempKey)) {
                        Field field = declaredFieldMap.get(tempKey);
                        switch (field.getType().getSimpleName()) {
                            case "Integer":
                                if (!"originalCount".equals(tempKey)) {
                                    cq.eq(tempKey, Integer.parseInt(requestMap.get(key).toString()));
                                }
                                break;
                            case "String":
                                if (isEq) {
                                    if (!"originalCount".equals(tempKey)) {
                                        cq.eq(tempKey, requestMap.get(key).toString());
                                    }
                                } else {
                                    cq.like(tempKey, requestMap.get(key).toString());
                                }
                                break;
                            case "Long":
                                if (!"categoryId".equals(tempKey)) {//categoryId 默认添加，此处排除
                                    cq.eq(tempKey, Long.parseLong(requestMap.get(key).toString()));
                                }
                                break;
                            default:
                                break;
                        }
                    }

                    //处理更新时间根据YYYYMMdd进行eq的问题
                    String updateTimeDay = requestMap.get("updateTimeDay");
                    if (FlymeUtils.isNotEmpty(updateTimeDay)) {
                        try {
                            Date begin = DateUtil.parse(updateTimeDay, "yyyyMMdd");
                            Date end = new Date(begin.getTime() + 1000 * 60 * 60 * 24L);
                            cq.lambda().between(ArcInfo::getUpdateTime, begin, end);
                        } catch (Exception e) {
                            log.error("根据删除时间查询日期格式转换错误", e);
                            ApiAssert.failure("根据删除时间查询日期格式转换错误");
                        }
                    }
                }
            }


        });
        //特殊字段查询处理
        String storeRoomIds = requestMap.get("storeRoomIds");
        if (FlymeUtils.isNotEmpty(storeRoomIds)) {
            String[] storeRoomIdsArr = storeRoomIds.toString().split(",");
            cq.lambda().in(ArcInfo::getStoreRoomId, Arrays.stream(storeRoomIdsArr).map(item -> {
                return Long.parseLong(item);
            }).collect(Collectors.toList()));
        }
        //基于id集合进行查询
        String arcInfoIdsStr = requestMap.get("arcInfoIds");
        if (FlymeUtils.isNotEmpty(arcInfoIdsStr)) {
            String[] arcInfoIdArr = arcInfoIdsStr.toString().split(",");
            cq.lambda().in(ArcInfo::getArcInfoId, Arrays.stream(arcInfoIdArr).map(item -> {
                return Long.parseLong(item);
            }).collect(Collectors.toList()));
        }

        String parentIdIsNull = requestMap.get("parentIdIsNull");
        if (FlymeUtils.isNotEmpty(parentIdIsNull)) {
            cq.isNull("parentId");
        }

        String parentIds = requestMap.get("parentIds");
        if (FlymeUtils.isNotEmpty(parentIds)) {
            //cq.isNull("parentId");
            cq.in("parentId", Arrays.stream(parentIds.split(",")).map(item -> {
                return Long.parseLong(item.toString());
            }).collect(Collectors.toList()));
        }
        //关联门类id
        String refCategoryId = requestMap.get("refCategoryId_");
        if (FlymeUtils.isNotEmpty(refCategoryId)) {
            String srcRefArcInfoId = requestMap.get("srcRefArcInfoId_");
            if (FlymeUtils.isNotEmpty(srcRefArcInfoId)) {
                List<ArcRefRecord> arcRefRecords = this.arcRefRecordService.list(new QueryWrapper<ArcRefRecord>().lambda()
//                        .eq(ArcRefRecord::getRefType,1)
                        .eq(ArcRefRecord::getSrcArcInfoId, srcRefArcInfoId)
                        .eq(ArcRefRecord::getTargetCategoryId, refCategoryId));
                if (FlymeUtils.isNotEmpty(arcRefRecords)) {
                    cq.in("arcInfoId", arcRefRecords.stream().map(item -> {
                        return item.getTargetArcInfoId();
                    }).collect(Collectors.toList()));
                } else {
                    cq.eq("arcInfoId", 1111L);
                }
            }
        }
        //编研素材字段处理
        //TODO 假设分库   则编研素材关联表必须基于数据库进行复制
        String compilationId = requestMap.get("compilationId");
        if (FlymeUtils.isNotEmpty(compilationId)) {
            Long compilationIdLong = Long.parseLong(compilationId);
            LambdaQueryWrapper<ArcCompilationRef> refQuery = new LambdaQueryWrapper<>();
            refQuery.eq(ArcCompilationRef::getCompilationId, compilationIdLong);
            refQuery.select(ArcCompilationRef::getArcInfoId);
            List<ArcCompilationRef> objs = this.arcCompilationRefService.list(refQuery);
            if (FlymeUtils.isEmpty(objs)) {
                cq.eq("arcInfoId", 111L);
            } else {
                List<Long> arcInfoIds = objs.stream().map(item -> {
                    return item.getArcInfoId();
                }).collect(Collectors.toList());
                cq.in("arcInfoId", arcInfoIds);
            }

            //cq.inSql("arcInfoId","select arcInfoId from arc_compilation_ref where compilationId = "+compilationIdLong);
        }
        //过滤用户负责机构的数据
        Object notFilterUnitId = requestMap.get("notFilterUnitId");
        if (FlymeUtils.isEmpty(notFilterUnitId)) {
            Long qzId = this.arcCategoryService.getById(info.getCategoryId()).getQzId();
            List<Long> unitIds = userUnitService.getLoginUserUnitIds(qzId, null);
            if (FlymeUtils.isNotEmpty(unitIds)) {
                cq.lambda().in(ArcInfo::getUnitId, unitIds);
            }
        }

        //搜藏
        if (StrUtil.isNotEmpty(requestMap.get("collect"))) {
            List<Long> arcInfoIds = arcInfoCollectService.getArcInfoIds(requestMap, OpenHelper.getUserId());
            if (CollUtil.isNotEmpty(arcInfoIds)) {
                cq.lambda().in(ArcInfo::getArcInfoId, arcInfoIds);
            } else {
                cq.lambda().eq(ArcInfo::getArcInfoId, 0);
            }
        }

        //原文数量检索
        if (StrUtil.isNotEmpty(requestMap.get("originalCount"))) {
            int originalCount = MapUtil.getInt(requestMap, "originalCount").intValue();
            if (originalCount == 0) {
                cq.and(ew -> {
                    ew.eq("originalCount", originalCount).or().isNull("originalCount");
                });
            } else {
                cq.eq("originalCount", originalCount);
            }
        }

        //3 排序
        Object orders = requestMap.get("orders");//多个用逗号隔开
        Object sorts = requestMap.get("sorts");//多个用逗号隔开
        if (FlymeUtils.isNotEmpty(orders)) {
            List<String> orderList = Arrays.asList(orders.toString().split(","));
            List<String> sortList = new ArrayList();
            if (FlymeUtils.isNotEmpty(sorts)) {
                sortList = Arrays.asList(sorts.toString().split(","));
            }
            for (int i = 0; i < orderList.size(); i++) {
                String sortColumn = orderList.get(i);
                ArcField obj = fieldMap.get(sortColumn);
                if (FlymeUtils.isNotEmpty(obj)) {
                    if (ArchiveEnumInteger.IS_TRUE.getCode().equals(obj.getIsBlob())) {
                        //增加要排序的扩展字段别名  mysql 5.7.9+ 支持
                        //cq.addSelect("info.expand->'$." + sortColumn + "' as "+sortColumn);
                        //扩展字段排序
                        if (sortList.size() <= i) {//默认排序
                            cq.orderByDesc(getExpandColumnWithType(sortColumn, obj.getDataType(), obj.getInType()));
                        } else {//基于排序字段进行排序
                            if ("ASC".equals(sortList.get(i))) {
                                //"json_extract(expand,\"$." + sortColumn + "\")"
                                cq.orderByAsc(getExpandColumnWithType(sortColumn, obj.getDataType(), obj.getInType()));
                            } else {
                                //"json_extract(expand,\"$." + sortColumn + "\")"
                                cq.orderByDesc(getExpandColumnWithType(sortColumn, obj.getDataType(), obj.getInType()));
                            }
                        }
                    } else {
                        //非扩展字段排序
                        if (sortList.size() < i) {//默认排序
                            cq.orderByDesc(sortColumn);
                        } else {//基于排序字段进行排序
                            if ("ASC".equals(sortList.get(i))) {
                                cq.orderByAsc(getColumnWithType(sortColumn, obj.getDataType(), obj.getInType()));
                            } else {
                                cq.orderByDesc(getColumnWithType(sortColumn, obj.getDataType(), obj.getInType()));
                            }
                        }
                    }
                } else {
                    if ("originalCount".equals(sortColumn) || "childCount".equals(sortColumn) || "refCount".equals(sortColumn)) {
                        //非扩展字段排序
                        if (sortList.size() <= i) {//默认排序
                            cq.orderByDesc(sortColumn);
                        } else {//基于排序字段进行排序
                            if ("ASC".equals(sortList.get(i))) {
                                cq.orderByAsc(getColumnWithType(sortColumn, obj.getDataType(), obj.getInType()));
                            } else {
                                cq.orderByDesc(getColumnWithType(sortColumn, obj.getDataType(), obj.getInType()));
                            }
                        }
                    }
                }
            }
        } else {
            //基于门类默认字段排序
            List<ArcField> orderArcInfo = fields.stream().filter(item -> {
                return ArchiveEnumInteger.IS_TRUE.getCode().equals(item.getOutIsOrder());
            }).sorted(Comparator.comparing(ArcField::getOutOrderSeq)).collect(Collectors.toList());
            if (FlymeUtils.isNotEmpty(orderArcInfo)) {
                orderArcInfo.forEach(item -> {
                    if (ArchiveEnumInteger.IS_TRUE.getCode().equals(item.getIsBlob())) {
                        //增加要排序的扩展字段别名  mysql 5.7.9+ 支持
//                        cq.addSelect("info.expand->'$." + item.getFieldName() + "' as "+item.getFieldName());
                        //扩展字段排序
                        if ("ASC".equals(item.getOutOrderType())) {
                            cq.orderByAsc(getExpandColumnWithType(item.getFieldName(), item.getDataType(), item.getInType()));
                        } else {
                            cq.orderByDesc(getExpandColumnWithType(item.getFieldName(), item.getDataType(), item.getInType()));
                        }
                    } else {
                        //非扩展字段排序
                        if ("ASC".equals(item.getOutOrderType())) {
                            cq.orderByAsc(getColumnWithType(item.getFieldName(), item.getDataType(), item.getInType()));
                        } else {
                            cq.orderByDesc(getColumnWithType(item.getFieldName(), item.getDataType(), item.getInType()));
                        }
                    }
                });
            }
        }

    }


    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public ResultBody beforePageList(CriteriaQuery<ArcInfo> cq, ArcInfo info, EntityMap requestMap) {
        //1 根据门类id，查询表后缀，确定zuo 分片
        ApiAssert.isNotEmpty("门类id不能为空", info);
        ApiAssert.isNotEmpty("门类id不能为空", info.getCategoryId());
//        CriteriaQuery<ArcCategorySuffix> suffixCriteriaQuery = new CriteriaQuery<ArcCategorySuffix>(ArcCategorySuffix.class);
//        suffixCriteriaQuery.lambda().eq(ArcCategorySuffix::getCategoryId,info.getCategoryId());
//        ArcCategorySuffix suffixObj = arcCategorySuffixService.getOne(suffixCriteriaQuery);

        Object categorySecondId = requestMap.get("categorySecondId_");
        if (FlymeUtils.isNotEmpty(categorySecondId)) {
            //处理二级分类
            QueryWrapper<ArcSecondField> arcSecondFieldQueryWrapper = new QueryWrapper<>();
            arcSecondFieldQueryWrapper.lambda().eq(ArcSecondField::getCategorySecondId, Long.parseLong(categorySecondId.toString()));
            List<ArcSecondField> list = this.arcSecondFieldService.list(arcSecondFieldQueryWrapper);
            if (FlymeUtils.isEmpty(list)) {
                //如果二级分类没配置条件，则随便增加一条查询不到的
                requestMap.put("arcInfoId", 111L);
            } else {
                list.forEach(item -> {
                    if (item.getQueryType().equals(QueryTypeEnum.QUERY_TYPE_5.getCode())) {
                        requestMap.put("Begin" + item.getFieldCnName(), item.getQueryVal());
                        requestMap.put("End" + item.getFieldCnName(), item.getQueryValEnd());
                    } else if (item.getQueryType().equals(QueryTypeEnum.QUERY_TYPE_1.getCode())) {
                        //_EQ_
                        requestMap.put(item.getFieldName() + "_EQ_", item.getQueryVal());
                    } else {
                        requestMap.put(item.getFieldName(), item.getQueryVal());
                    }
                });
            }
        }
        genArcInfoQuery(cq, info, requestMap);


        Object allParamQuery = requestMap.get("allParamQuery_");
        if (FlymeUtils.isNotEmpty(allParamQuery) && "all".equals(allParamQuery)) {
            Object queryStr = requestMap.get("queryStr");
            ApiAssert.isNotEmpty("全文检索查询条件不能为空", queryStr);
            buildAllArcInfoQuery(cq, info.getCategoryId(), queryStr.toString(), requestMap);
        }

        //组合条件查询
        buildCombinedConditionQuery(cq, requestMap);

        return ResultBody.ok();
    }

    private void buildCombinedConditionQuery(CriteriaQuery<ArcInfo> cq, EntityMap requestMap) {
        String handlerType = requestMap.get("handlerType");
        if (StrUtil.isNotEmpty(handlerType)) {
            String paramArry = requestMap.get("paramArry");
            List<ArcInfoQuery> objects = JSONArray.parseArray(paramArry, ArcInfoQuery.class);

            switch (handlerType) {
                //     条件查询
                case "condition":

                    cq.and(c -> {
                        objects.forEach(object -> {
                            String after = object.getAfter();
                            if ("and".equals(object.getBefore())) {
                                switch (after) {
                                    case "1":
                                        if (ArchiveEnumInteger.IS_TRUE.getCode().equals(object.getIsBlob())) {
                                            c.eq(getExpandColumn(object.getFieldName()), object.getValue());
                                        } else {
                                            c.eq(object.getFieldName(), object.getValue());
                                        }
                                        break;
                                    case "2":
                                        if (ArchiveEnumInteger.IS_TRUE.getCode().equals(object.getIsBlob())) {
                                            c.lt(getExpandColumn(object.getFieldName()), object.getValue());
                                        } else {
                                            c.lt(object.getFieldName(), object.getValue());
                                        }
                                        break;
                                    case "3":
                                        if (ArchiveEnumInteger.IS_TRUE.getCode().equals(object.getIsBlob())) {
                                            c.le(getExpandColumn(object.getFieldName()), object.getValue());
                                        } else {
                                            c.le(object.getFieldName(), object.getValue());
                                        }
                                        break;
                                    case "4":
                                        if (ArchiveEnumInteger.IS_TRUE.getCode().equals(object.getIsBlob())) {
                                            c.gt(getExpandColumn(object.getFieldName()), object.getValue());
                                        } else {
                                            c.gt(object.getFieldName(), object.getValue());
                                        }
                                        break;
                                    case "5":
                                        if (ArchiveEnumInteger.IS_TRUE.getCode().equals(object.getIsBlob())) {
                                            c.le(getExpandColumn(object.getFieldName()), object.getValue());
                                        } else {
                                            c.le(object.getFieldName(), object.getValue());
                                        }
                                        break;
                                    case "6":
                                        if (ArchiveEnumInteger.IS_TRUE.getCode().equals(object.getIsBlob())) {
                                            c.like(getExpandColumn(object.getFieldName()), object.getValue());
                                        } else {
                                            c.like(object.getFieldName(), object.getValue());
                                        }
                                        break;
                                    case "7":
                                        if (ArchiveEnumInteger.IS_TRUE.getCode().equals(object.getIsBlob())) {
                                            c.between(getExpandColumn(object.getFieldName()), StrUtil.splitToArray(object.getValue(), ',')[0], StrUtil.splitToArray(object.getValue(), ',')[1]);
                                        } else {
                                            c.between(object.getFieldName(), StrUtil.splitToArray(object.getValue(), ',')[0], StrUtil.splitToArray(object.getValue(), ',')[1]);
                                        }
                                        break;
                                }
                            } else {
                                switch (after) {
                                    case "1":
                                        if (ArchiveEnumInteger.IS_TRUE.getCode().equals(object.getIsBlob())) {
                                            c.or(cc -> cc.eq(getExpandColumn(object.getFieldName()), object.getValue()));
                                        } else {
                                            c.or(cc -> cc.eq(object.getFieldName(), object.getValue()));
                                        }
                                        break;
                                    case "2":
                                        if (ArchiveEnumInteger.IS_TRUE.getCode().equals(object.getIsBlob())) {
                                            c.or(cc -> cc.lt(getExpandColumn(object.getFieldName()), object.getValue()));
                                        } else {
                                            c.or(cc -> cc.lt(object.getFieldName(), object.getValue()));
                                        }
                                        break;
                                    case "3":
                                        if (ArchiveEnumInteger.IS_TRUE.getCode().equals(object.getIsBlob())) {
                                            c.or(cc -> cc.le(getExpandColumn(object.getFieldName()), object.getValue()));
                                        } else {
                                            c.or(cc -> cc.le(object.getFieldName(), object.getValue()));
                                        }
                                        break;
                                    case "4":
                                        if (ArchiveEnumInteger.IS_TRUE.getCode().equals(object.getIsBlob())) {
                                            c.or(cc -> cc.gt(getExpandColumn(object.getFieldName()), object.getValue()));
                                        } else {
                                            c.or(cc -> cc.gt(object.getFieldName(), object.getValue()));
                                        }
                                        break;
                                    case "5":
                                        if (ArchiveEnumInteger.IS_TRUE.getCode().equals(object.getIsBlob())) {
                                            c.or(cc -> cc.le(getExpandColumn(object.getFieldName()), object.getValue()));
                                        } else {
                                            c.or(cc -> cc.le(object.getFieldName(), object.getValue()));
                                        }
                                        break;
                                    case "6":
                                        if (ArchiveEnumInteger.IS_TRUE.getCode().equals(object.getIsBlob())) {
                                            c.or(cc -> cc.like(getExpandColumn(object.getFieldName()), object.getValue()));
                                        } else {
                                            c.or(cc -> cc.like(object.getFieldName(), object.getValue()));
                                        }
                                        break;
                                    case "7":
                                        if (ArchiveEnumInteger.IS_TRUE.getCode().equals(object.getIsBlob())) {
                                            c.or(cc -> cc.between(getExpandColumn(object.getFieldName()), StrUtil.splitToArray(object.getValue(), ',')[0], StrUtil.splitToArray(object.getValue(), ',')[1]));
                                        } else {
                                            c.or(cc -> cc.between(object.getFieldName(), StrUtil.splitToArray(object.getValue(), ',')[0], StrUtil.splitToArray(object.getValue(), ',')[1]));
                                        }
                                        break;
                                }
                            }
                        });
                    });
                    break;
                //    组合查询
                case "combination":
                    for (ArcInfoQuery object : objects) {
                        if (ArchiveEnumInteger.IS_TRUE.getCode().equals(object.getIsBlob())) {
                            cq.in(getExpandColumn(object.getFieldName()), object.getValue());
                        } else {
                            cq.in(object.getFieldName(), StrUtil.split(object.getValue(), ','));
                        }
                    }
                    break;
            }

        }
    }

    @Override
    public ResultBody beforeListEntityMap(CriteriaQuery<ArcInfo> cq, ArcInfo info, EntityMap requestMap) {
        ApiAssert.isNotEmpty("门类id不能为空", info);
        ApiAssert.isNotEmpty("门类id不能为空", info.getCategoryId());
//        CriteriaQuery<ArcCategorySuffix> suffixCriteriaQuery = new CriteriaQuery<ArcCategorySuffix>(ArcCategorySuffix.class);
//        suffixCriteriaQuery.lambda().eq(ArcCategorySuffix::getCategoryId,info.getCategoryId());
//        ArcCategorySuffix suffixObj = arcCategorySuffixService.getOne(suffixCriteriaQuery);
        genArcInfoQuery(cq, info, requestMap);
        return ResultBody.ok();
    }

    @Override
    public ResultBody afterListEntityMap(CriteriaQuery<ArcInfo> cq, List<EntityMap> data, ResultBody resultBody) {
        //解析返回数据中的expand字段
        if (FlymeUtils.isNotEmpty(data)) {
            data.forEach(item -> {
                String expand = item.get("expand");
                if (FlymeUtils.isNotEmpty(expand)) {
                    EntityMap map = JsonUtils.jsonToEntityMap(expand);
                    item.putAll(map);
                }
                //去除 expand字段
                item.remove("expand");
            });

        }
        return resultBody;
    }


    @Override
    public ResultBody allCategoryQuery(Map param) {
        Object qzId = param.get("qzId");
        ApiAssert.isNotEmpty("全宗Id不能为空", qzId);
//        Object queryStr = param.get("queryStr");
//        ApiAssert.isNotEmpty("查询条件不能为空",queryStr);
        LambdaQueryWrapper<ArcCategory> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.ne(ArcCategory::getType, CategoryTypeEnum.CATEGORY_TYPE_0.getCode())
                .likeRight(ArcCategory::getSysCode, "A02");
        //过滤用户角色权限
        lambdaQueryWrapper.inSql(ArcCategory::getCategoryId, "select cu.categoryId from arc_category_user cu " +
                "left join base_role_user ru on cu.roleId = ru.roleId where ru.userId = " + OpenHelper.getUserId());


        //根据全宗id过滤   或   类型属于系统级别
        lambdaQueryWrapper.and(wrap -> {
            wrap.eq(ArcCategory::getQzId, Long.parseLong(qzId.toString()))
                    .or().eq(ArcCategory::getIsSystem, ArchiveEnumInteger.IS_SYSTEM.getCode());
        });


        List<ArcCategory> categories = this.arcCategoryService.list(lambdaQueryWrapper);
        Map<Long, ArcCategory> categoryMap = categories.stream()
                .collect(Collectors.toMap(ArcCategory::getCategoryId, ArcCategory -> ArcCategory));
        List<Future<Long>> futures = new ArrayList<>();
        Long userId = OpenHelper.getUserId();
        categories.forEach(item -> {
            final Map map = new HashMap();
            map.putAll(param);
            map.put("tempUserId_", userId);
            Future<Long> future = syncService.categoryHasArcQuery(item.getCategoryId(), null, map);
            futures.add(future);
        });
        List<ArcCategory> result = new ArrayList<>();
        futures.forEach(item -> {
            try {
                Long l = item.get();
                if (!l.equals(0L)) {
                    ArcCategory category = categoryMap.get(l);
                    if (FlymeUtils.isNotEmpty(category)) {
                        result.add(category);
                    }
                }

            } catch (Exception e) {
                log.error("获取门类异常", e);
                ApiAssert.failure("获取门类异常");
            }
        });
        return ResultBody.ok(result);
    }

    private Map<String, String> initDictMap(EntityMap param) {
        Map dictQueryParam = new HashMap();
        dictQueryParam.put("qzId", param.getLong("qzId"));
        ResultBody result = arcDictService.listEntityMap(dictQueryParam);
        List<EntityMap> dictList = (List) result.getData();

        Map dbDict = dictList.stream().filter(item -> {
            return FlymeUtils.isNotEmpty(item.get("dictCode")) && FlymeUtils.isNotEmpty(item.get("dictName"));
        }).collect(Collectors.toMap(item -> {
            return item.get("dictCode").toString();
        }, item -> {
            return item.get("dictName").toString();
        }));
        return dbDict;
    }

    private Map<String, String> initUnitMap(EntityMap param) {

        //初始化机构名称字典
        QueryWrapper<SysDept> query = new QueryWrapper();
        query.lambda().eq(SysDept::getCompanyId, param.getLong("qzId"));
        List<SysDept> deptList = this.sysDeptService.list(query);
        Map unitDict = deptList.stream().collect(Collectors.toMap(item -> {
            return item.getDeptId().toString();
        }, item -> {
            return item.getDeptName();
        }));
        return unitDict;
    }

    private List<String> findMapValReturnKeyList(Map<String, String> map, String findVal) {
        if (FlymeUtils.isEmpty(map)) {
            return null;
        }
        if (FlymeUtils.isEmpty(findVal)) {
            return null;
        }
        return map.keySet().stream().filter(item -> {
            return map.get(item).indexOf(findVal) >= 0;
        }).collect(Collectors.toList());
    }

    @Override
    public Map buildAllArcInfoQuery(CriteriaQuery<ArcInfo> cq, Long categoryId, String queryStr, EntityMap param) {
        Object fieldName = param.get("fieldName");
        LambdaQueryWrapper<ArcField> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(ArcField::getCategoryId, categoryId);
        if (FlymeUtils.isNotEmpty(fieldName)) {
            lambdaQueryWrapper.eq(ArcField::getFieldName, fieldName.toString());
        } else {
            lambdaQueryWrapper.eq(ArcField::getOutIsShow, ArchiveEnumInteger.IS_TRUE.getCode());
        }
        List<ArcField> fieldList = this.arcFieldService.list(lambdaQueryWrapper);
        if (FlymeUtils.isEmpty(fieldList)) {
            return null;
        }
        Field[] declaredFields = ArcInfo.class.getDeclaredFields();
        Map<String, Field> declaredFieldNamesMap = Arrays.asList(declaredFields).stream().collect(Collectors.toMap(item -> {
            return item.getName();
        }, Field -> Field));
        AtomicBoolean isFirst = new AtomicBoolean(true);

        if (FlymeUtils.isEmpty(param.get("qzId"))) {
            ArcCategory category = this.arcCategoryService.getById(categoryId);
            param.put("qzId", category.getQzId());
        }
        final Map<String, String> dictMap = new HashMap();
        final Map<String, String> unitIdMap = new HashMap();


        cq.and(wrapper -> {
            fieldList.forEach(item -> {
                if ("unitId".equals(item.getFieldName())) {
                    //特殊字段机构
                    if (FlymeUtils.isEmpty(unitIdMap)) {
                        Map<String, String> m = initUnitMap(param);
                        if (FlymeUtils.isNotEmpty(m)) {
                            unitIdMap.putAll(m);
                        }
                    }
                    List<String> unitIds = findMapValReturnKeyList(unitIdMap, queryStr);
                    if (FlymeUtils.isEmpty(unitIds)) {
                        unitIds = new ArrayList<>();
                        unitIds.add("9999");
                    }
                    List<Long> unitIdsLong = unitIds.stream().map(id -> {
                        return Long.parseLong(id);
                    }).collect(Collectors.toList());
                    if (isFirst.getAndSet(false)) {
                        wrapper.in(item.getFieldName(), unitIdsLong);
                    } else {
                        wrapper.or().in(item.getFieldName(), unitIdsLong);
                    }
                } else if (item.getInType() == 6 || item.getInType() == 4) {
                    //特殊字段 字典
                    if (FlymeUtils.isEmpty(dictMap)) {
                        Map<String, String> m = initDictMap(param);
                        if (FlymeUtils.isNotEmpty(m)) {
                            dictMap.putAll(m);
                        }
                    }
                    List<String> dictCodes = findMapValReturnKeyList(dictMap, queryStr);
                    if (FlymeUtils.isEmpty(dictCodes)) {
                        dictCodes = new ArrayList<>();
                        dictCodes.add("noDictCode_");
                    }
                    if (declaredFieldNamesMap.containsKey(item.getFieldName())) {
                        if (isFirst.getAndSet(false)) {
                            wrapper.in(item.getFieldName(), dictCodes);
                        } else {
                            wrapper.or().in(item.getFieldName(), dictCodes);
                        }
                    } else {
                        if (ArchiveEnumInteger.IS_TRUE.getCode().equals(item.getIsBlob())) {
                            //扩展字段

                            if (isFirst.getAndSet(false)) {
                                wrapper.in(getExpandColumn(item.getFieldName()), dictCodes);
                            } else {
                                wrapper.or().in(getExpandColumn(item.getFieldName()), dictCodes);
                            }
                        } else {
                            //普通字段
                            if (isFirst.getAndSet(false)) {
                                wrapper.in(item.getFieldName(), dictCodes);
                            } else {
                                wrapper.or().in(item.getFieldName(), dictCodes);
                            }
                        }
                    }
                } else {
                    if (declaredFieldNamesMap.containsKey(item.getFieldName())) {
                        switch (declaredFieldNamesMap.get(item.getFieldName()).getType().getSimpleName()) {
                            case "Long":
                                if (NumberUtil.isLong(queryStr)) {
                                    if (isFirst.getAndSet(false)) {
                                        wrapper.eq(item.getFieldName(), Long.parseLong(queryStr));
                                    } else {
                                        wrapper.or().eq(item.getFieldName(), Long.parseLong(queryStr));
                                    }
                                }
                                ;
                                break;
                            case "Integer":
                                if (NumberUtil.isInteger(queryStr)) {
                                    if (isFirst.getAndSet(false)) {
                                        wrapper.eq(item.getFieldName(), Integer.parseInt(queryStr));
                                    } else {
                                        wrapper.or().eq(item.getFieldName(), Integer.parseInt(queryStr));
                                    }
                                }
                                ;
                                break;
                            case "String":
                                if (isFirst.getAndSet(false)) {
                                    wrapper.like(item.getFieldName(), queryStr);
                                } else {
                                    wrapper.or().like(item.getFieldName(), queryStr);
                                }
                                break;
                        }
                    } else {
                        if (ArchiveEnumInteger.IS_TRUE.getCode().equals(item.getIsBlob())) {
                            //扩展字段

                            if (isFirst.getAndSet(false)) {
                                wrapper.like(getExpandColumn(item.getFieldName()), queryStr);
                            } else {
                                wrapper.or().like(getExpandColumn(item.getFieldName()), queryStr);
                            }
                        } else {
                            //普通字段
                            if (isFirst.getAndSet(false)) {
                                wrapper.like(item.getFieldName(), queryStr);
                            } else {
                                wrapper.or().like(item.getFieldName(), queryStr);
                            }
                        }
                    }
                }
            });
        });
        return param;
    }

    @Override
    public List<EntityMap> afterPageList(CriteriaQuery<ArcInfo> cq, List<EntityMap> data, ResultBody resultBody) {

        //解析返回数据中的expand字段
        if (FlymeUtils.isNotEmpty(data)) {
            EntityMap requestMap = new EntityMap();
            requestMap.put("qzId", cq.getLong("qzId"));
            requestMap.put("categoryId", cq.getLong("categoryId"));
            List<Long> ids = arcInfoCollectService.getArcInfoIds(requestMap, OpenHelper.getUserId());
            data.forEach(item -> {
                String expand = item.get("expand");
                if (FlymeUtils.isNotEmpty(expand)) {
                    EntityMap map = JsonUtils.jsonToEntityMap(expand);
                    item.putAll(map);
                }
                //去除 expand字段
                item.remove("expand");
                item.put("isCollect", ids.contains(item.getLong("arcInfoId")) ? 1 : 0);
            });

        }
        return data;
    }

    @Override
    public ResultBody afterEdit(CriteriaUpdate cu, ArcInfo t, EntityMap extra) {

        //String expand = t.getExpand();
        //if (FlymeUtils.isNotEmpty(expand)) {
        //    EntityMap map1 = JsonUtils.jsonToEntityMap(expand);
        //    Map<String, String> map = JSON.parseObject(JSON.toJSONString(t), new TypeReference<Map<String, String>>() {
        //    });
        //    map.remove("expand");
        //    map1.putAll(map);
        //    return ResultBody.ok("更新成功",map1);
        //}
        //return ResultBody.ok("更新成功",t);
        extra.put("categoryId", t.getCategoryId());
        extra.put("arcInfoId", t.getArcInfoId());
        return get(extra);
    }

    /**
     * 归档类型变更
     *
     * @param param
     * @return
     */
    @Override
    public ResultBody arcStatusChange(Map param) {
        Object categoryId = param.get("categoryId");
        Object arcInfoIds = param.get("arcInfoIds");
        Object qzId = param.get("qzId");
        Object bizType = param.get("bizType");
        ApiAssert.isNotEmpty("门类id不能为空", categoryId);
        ApiAssert.isNotEmpty("归档变更类型不能为空", bizType);
        List<String> arcInfoIdsList = null;
        if (!"6".equals(bizType.toString())) {//彻底清空 门类回收站不需要传档案id
            ApiAssert.isNotEmpty("档案id不能为空", arcInfoIds);
            arcInfoIdsList = Arrays.asList(arcInfoIds.toString().split(","));
            ApiAssert.isNotEmpty("档案不能为空", arcInfoIdsList);
        }


        switch (bizType.toString()) {
            case "0"://加入待归档还原
                CriteriaUpdate<ArcInfo> criteriaUpdate = new CriteriaUpdate<ArcInfo>();
                criteriaUpdate.lambda().in(ArcInfo::getArcInfoId, arcInfoIdsList.stream().map(item -> {
                    return Long.parseLong(item);
                }).collect(Collectors.toList()))
                        .eq(ArcInfo::getCategoryId, Long.parseLong(categoryId.toString()));
                ArcInfo info = new ArcInfo();
                info.setStatus(ArcStatusEnum.ARC_STATUS_0.getCode());
                this.update(info, criteriaUpdate);
                //消息记录
                for (String s : arcInfoIdsList) {
                    this.arcUseRemindService.createRemid(3, "驳回了你的档案归档申请", MapUtil.getLong(param, "qzId"), null, OpenHelper.getUserId(), Long.valueOf(s));
                }

                break;
            case "1"://加入待归档

                CriteriaUpdate<ArcInfo> criteriaUpdate1 = new CriteriaUpdate<ArcInfo>();
                criteriaUpdate1.lambda().in(ArcInfo::getArcInfoId, arcInfoIdsList.stream().map(item -> {
                    return Long.parseLong(item);
                }).collect(Collectors.toList())).eq(ArcInfo::getCategoryId, Long.parseLong(categoryId.toString()));

                ArcInfo info1 = new ArcInfo();
                info1.setStatus(ArcStatusEnum.ARC_STATUS_1.getCode());
                this.update(info1, criteriaUpdate1);
                //消息记录
                for (String s : arcInfoIdsList) {
                    this.arcUseRemindService.createRemid(3, "提交了档案归档申请", MapUtil.getLong(param, "qzId"), OpenHelper.getUserId(), null, Long.valueOf(s));
                }
                break;
            case "2"://归档
                //只有简化模式与卷内可以归档
                ArcCategory category = arcCategoryService.getById(Long.parseLong(categoryId.toString()));
                if (!CategoryTypeEnum.CATEGORY_TYPE_3.equals(category.getType())
                        && !CategoryTypeEnum.CATEGORY_TYPE_4.equals(category.getType())) {
                    CriteriaQuery<ArcConfig> configCriteriaQuery = new CriteriaQuery<ArcConfig>(ArcConfig.class);
                    configCriteriaQuery.lambda().eq(ArcConfig::getSrcCategoryId, Long.parseLong(categoryId.toString()));
                    List<ArcConfig> configs = arcConfigService.list(configCriteriaQuery);
                    if (FlymeUtils.isEmpty(configs)) {
                        return ResultBody.failed("该门类没有归档配置，不能进行归档");
                    }
                    if (configs.size() > 1) {
                        return ResultBody.failed("该门类存在多条归档配置，不能进行归档");
                    }
                    //档号设置相关参数
                    Object arcParamObj = param.get("arcParam");
                    ApiAssert.isNotEmpty("归档信息不能为空", arcParamObj);
                    Map<String, Object> arcParamMap = JsonUtils.jsonToBean(arcParamObj.toString(), Map.class);
                    List<Long> arcInfoIdsLong = arcInfoIdsList.stream().map(item -> {
                        return Long.parseLong(item);
                    }).collect(Collectors.toList());
                    Object arcNumFmtObj = param.get("arcNumFmt");
                    ApiAssert.isNotEmpty("档号规则不能为空", arcParamObj);
                    List<ArcNumFmt> arcNumFmt = JsonUtils.json2list(arcNumFmtObj.toString(), ArcNumFmt.class);
                    if (FlymeUtils.isEmpty(arcNumFmt)) {
                        ApiAssert.failure("目标门类没有配置档号规则");
                    }
                    srcArcInfo2TargetArcInfo(arcInfoIdsLong, configs.get(0), arcParamMap, arcNumFmt);
                    this.arcOriginalService.srcArcOriginal2TargetArcOriginal(arcInfoIdsLong, configs.get(0));
                    //消息记录
                    for (String s : arcInfoIdsList) {
                        this.arcUseRemindService.createRemid(3, "通过了你的档案归档申请", MapUtil.getLong(param, "qzId"), null, OpenHelper.getUserId(), Long.valueOf(s));
                    }
                } else {
                    return ResultBody.failed("只有简化模式和卷内可以归档");
                }
                break;
            case "3"://加入回收站（删除）
                ArcInfo recycleDel = new ArcInfo();
                recycleDel.setIsRecycle(ArchiveEnumInteger.IS_TRUE.getCode());
                recycleDel.setUpdateTime(new Date());
                recycleDel.setUpdateBy(OpenHelper.getUser().getNickName());


                CriteriaUpdate<ArcInfo> recycleDelUpdate = new CriteriaUpdate<ArcInfo>();
                recycleDelUpdate.lambda().in(ArcInfo::getArcInfoId, arcInfoIdsList.stream().map(item -> {
                    return Long.parseLong(item);
                }).collect(Collectors.toList())).eq(ArcInfo::getCategoryId, Long.parseLong(categoryId.toString()));
                this.update(recycleDel, recycleDelUpdate);
                //编研素材删除
                LambdaQueryWrapper<ArcCompilationRef> delQueryWrapper = new LambdaQueryWrapper<>();
                delQueryWrapper.in(ArcCompilationRef::getArcInfoId, arcInfoIdsList.stream().map(item -> {
                    return Long.parseLong(item);
                }).collect(Collectors.toList()));
                this.arcCompilationRefService.remove(delQueryWrapper);
                break;
            case "4"://回收站还原
                ArcInfo recycleBack = new ArcInfo();
                recycleBack.setIsRecycle(ArchiveEnumInteger.IS_FALSE.getCode());

                CriteriaUpdate<ArcInfo> recycleBackUpdate = new CriteriaUpdate<ArcInfo>();
                recycleBackUpdate.lambda().in(ArcInfo::getArcInfoId, arcInfoIdsList.stream().map(item -> {
                    return Long.parseLong(item);
                }).collect(Collectors.toList()))
                        .eq(ArcInfo::getCategoryId, Long.parseLong(categoryId.toString()))
                        .eq(ArcInfo::getIsRecycle, ArchiveEnumInteger.IS_TRUE.getCode());
                ;
                this.update(recycleBack, recycleBackUpdate);
                break;
            case "5"://彻底删除
                //先查出待删除档案
                LambdaQueryWrapper<ArcInfo> arcInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
                arcInfoLambdaQueryWrapper.in(ArcInfo::getArcInfoId, arcInfoIdsList.stream().map(item -> {
                    return Long.parseLong(item);
                }).collect(Collectors.toList())).eq(ArcInfo::getCategoryId, Long.parseLong(categoryId.toString()));
                List<ArcInfo> arcInfos5 = this.list(arcInfoLambdaQueryWrapper);
                Map<Long, List<ArcInfo>> deptCollect5 = arcInfos5.stream().collect(Collectors.groupingBy(ArcInfo::getUnitId));
                for (Long deptId : deptCollect5.keySet()) {
                    //删除档案后管理更新单位数据
                    SysDept sysDept = sysDeptService.getById(deptId);
                    SysCompany sysCompany = sysCompanyService.getById(sysDept.getCompanyId());
                    sysDeptService.update(new UpdateWrapper<SysDept>().lambda().eq(SysDept::getDeptId, sysDept.getDeptId()).set(SysDept::getArcInfoCount, sysDept.getArcInfoCount() - deptCollect5.get(deptId).size()));
                    sysCompanyService.update(new UpdateWrapper<SysCompany>().lambda().eq(SysCompany::getCompanyId, sysCompany.getCompanyId()).set(SysCompany::getArcInfoCount, sysCompany.getArcInfoCount() - deptCollect5.get(deptId).size()));
                }
                //删除案卷关系
                for (ArcInfo arcInfo : arcInfos5) {
                    if (ObjectUtil.isNotNull(arcInfo.getParentId())) {
                        arcRefRecordService.caculateArcRefCount(arcInfo.getParentId(), arcInfo.getCategoryId());
                    }
                }

                //List<Long> deptIds =arcInfos1.stream().map(ArcInfo::getUnitId).collect(Collectors.toList());
                //删除档案
                CriteriaDelete<ArcInfo> criteriaDelete = new CriteriaDelete<ArcInfo>();
                criteriaDelete.lambda().in(ArcInfo::getArcInfoId, arcInfoIdsList.stream().map(item -> {
                    return Long.parseLong(item);
                }).collect(Collectors.toList()))
                        .eq(ArcInfo::getCategoryId, Long.parseLong(categoryId.toString()));
                // 临时屏蔽
                //.eq(ArcInfo::getIsRecycle,ArchiveEnumInteger.IS_TRUE.getCode());
                this.remove(criteriaDelete);
                //删除原文
                this.arcOriginalService.delOriginal(arcInfoIdsList.stream().map(item -> {
                    return Long.parseLong(item);
                }).collect(Collectors.toList()), Long.parseLong(categoryId.toString()));
                break;


            case "6"://清空回收站
                //先查出待删除档案
                LambdaQueryWrapper<ArcInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                lambdaQueryWrapper.eq(ArcInfo::getCategoryId, Long.parseLong(categoryId.toString()))
                        .eq(ArcInfo::getIsRecycle, ArchiveEnumInteger.IS_TRUE.getCode());
                List<ArcInfo> arcInfos6 = this.list(lambdaQueryWrapper);
                Map<Long, List<ArcInfo>> deptCollect6 = arcInfos6.stream().collect(Collectors.groupingBy(ArcInfo::getUnitId));
                for (Long deptId : deptCollect6.keySet()) {
                    //删除档案后管理更新单位数据
                    SysDept sysDept = sysDeptService.getById(deptId);
                    SysCompany sysCompany = sysCompanyService.getById(sysDept.getCompanyId());
                    sysDeptService.update(new UpdateWrapper<SysDept>().lambda().eq(SysDept::getDeptId, sysDept.getDeptId()).set(SysDept::getArcInfoCount, sysDept.getArcInfoCount() - deptCollect6.get(deptId).size()));
                    sysCompanyService.update(new UpdateWrapper<SysCompany>().lambda().eq(SysCompany::getCompanyId, sysCompany.getCompanyId()).set(SysCompany::getArcInfoCount, sysCompany.getArcInfoCount() - deptCollect6.get(deptId).size()));
                }

                CriteriaDelete<ArcInfo> criteriaClear = new CriteriaDelete<ArcInfo>();
                criteriaClear.lambda().eq(ArcInfo::getCategoryId, Long.parseLong(categoryId.toString()))
                        .eq(ArcInfo::getIsRecycle, ArchiveEnumInteger.IS_TRUE.getCode());
                this.arcOriginalService.clearOriginal(Long.parseLong(categoryId.toString()), null);
                this.remove(criteriaClear);

                break;
            case "7"://加入待借
                CriteriaUpdate<ArcInfo> criteriaUpdateDj = new CriteriaUpdate<ArcInfo>();
                criteriaUpdateDj.lambda().in(ArcInfo::getArcInfoId, arcInfoIdsList.stream().map(item -> {
                    return Long.parseLong(item);
                }).collect(Collectors.toList()))
                        .eq(ArcInfo::getCategoryId, Long.parseLong(categoryId.toString()));
                ArcInfo infoDj = new ArcInfo();
                infoDj.setIsUse(ArchiveEnumInteger.IS_TRUE.getCode());
                this.update(infoDj, criteriaUpdateDj);

                CriteriaQuery<ArcInfo> criteriaQuery = new CriteriaQuery<ArcInfo>(ArcInfo.class);
                criteriaQuery.lambda().in(ArcInfo::getArcInfoId, arcInfoIdsList.stream().map(item -> {
                    return Long.parseLong(item);
                }).collect(Collectors.toList()))
                        .eq(ArcInfo::getCategoryId, Long.parseLong(categoryId.toString()));
                List<ArcInfo> arcInfos = list(criteriaQuery);
                arcUseService.addArcUse(arcInfos);
                break;
            case "8"://加入编研
                Object compilationId = param.get("compilationId");
                ApiAssert.isNotEmpty("编研素材类型不能为空", compilationId);
                //增加档案编研关联
                arcCompilationRefService.addCompilationRef(Long.parseLong(compilationId.toString()), Long.parseLong(categoryId.toString())
                        , arcInfoIdsList.stream().map(item -> {
                            return Long.parseLong(item);
                        }).collect(Collectors.toList()));
                ArcCompilationCategory compilationCategory = this.arcCompilationCategoryService.getById(Long.parseLong(compilationId.toString()));
                ApiAssert.isNotEmpty("编研素材类型不能为空", compilationId);
                CriteriaUpdate<ArcInfo> criteriaUpdateBy = new CriteriaUpdate<ArcInfo>();
                criteriaUpdateBy.lambda().in(ArcInfo::getArcInfoId, arcInfoIdsList.stream().map(item -> {
                    return Long.parseLong(item);
                }).collect(Collectors.toList()))
                        .eq(ArcInfo::getCategoryId, Long.parseLong(categoryId.toString()));
                ArcInfo infoBy = new ArcInfo();
                infoBy.setIsCompilation(ArchiveEnumInteger.IS_TRUE.getCode());
                infoBy.setCompilationName(compilationCategory.getName());
                this.update(infoBy, criteriaUpdateBy);

                break;
            case "9"://档案入库
                Object storeId = param.get("storeId");
                ApiAssert.isNotEmpty("入库id不能为空", storeId);
                //校验可入库状态
                //级联更新上级  如果为空则更新为已有切未满
                String storeLocationName = arcStoreRoomService.checkStoreAndChangeIsFull(Long.parseLong(storeId.toString()));
                CriteriaUpdate<ArcInfo> criteriaUpdateRk = new CriteriaUpdate<ArcInfo>();
                criteriaUpdateRk.lambda().in(ArcInfo::getArcInfoId, arcInfoIdsList.stream().map(item -> {
                    return Long.parseLong(item);
                }).collect(Collectors.toList()))
                        .eq(ArcInfo::getCategoryId, Long.parseLong(categoryId.toString()));
                ArcInfo infoRk = new ArcInfo();
                infoRk.setStoreRoomId(Long.parseLong(storeId.toString()));
                infoRk.setIsStore(ArchiveEnumInteger.IS_TRUE.getCode());
                infoRk.setStorageLocationName(storeLocationName);
                this.update(infoRk, criteriaUpdateRk);
                break;
            case "10"://加入销毁
                CriteriaUpdate<ArcInfo> criteriaUpdateBf = new CriteriaUpdate<ArcInfo>();
                criteriaUpdateBf.lambda().in(ArcInfo::getArcInfoId, arcInfoIdsList.stream().map(item -> {
                    return Long.parseLong(item);
                }).collect(Collectors.toList()))
                        .eq(ArcInfo::getCategoryId, Long.parseLong(categoryId.toString()));
                ArcInfo infoBf = new ArcInfo();
                infoBf.setIsDestory(ArchiveEnumInteger.IS_TRUE.getCode());
                this.update(infoBf, criteriaUpdateBf);
                List<ArcInfo> list = list(criteriaUpdateBf);
                arcDestoryService.destoryArcInfos(list);
                break;

            default:
                return ResultBody.failed("业务类型参数不存在");
        }
        return ResultBody.ok();
    }

    @Override
    public ArcInfo getArcInfoByField(ArcField arcField, Long userId, String val, Long categoryId, Boolean isLike) {
        ApiAssert.isNotEmpty("字段不能为空", arcField);
        ApiAssert.isNotEmpty("字段值不能为空", val);
        ApiAssert.isNotEmpty("查询档案 门类id不能为空", categoryId);
        CriteriaQuery<ArcInfo> criteriaQuery = new CriteriaQuery<ArcInfo>(ArcInfo.class);
        criteriaQuery.lambda()
                .eq(ArcInfo::getCategoryId, categoryId)
                .eq(ArcInfo::getIsRecycle, ArchiveEnumInteger.IS_FALSE);
        Field[] declaredFields = ArcInfo.class.getDeclaredFields();
        Map<String, Field> declaredFieldMap = Arrays.stream(declaredFields).collect(Collectors.toMap(Field::getName, Field -> Field));
        boolean isLong = false;
        //Long型字段处理
        if (declaredFieldMap.containsKey(arcField.getFieldName())
                && declaredFieldMap.get(arcField.getFieldName()).getType().getSimpleName().equals("Long")) {
            isLong = true;
        }
        if (declaredFieldMap.containsKey(arcField.getFieldName())) {
            //系统字段
            Field field = declaredFieldMap.get(arcField.getFieldName());
            switch (field.getType().getSimpleName()) {
                case "Integer":
                    criteriaQuery.eq(arcField.getFieldName(), Integer.parseInt(val));
                    break;
                case "String":
                    criteriaQuery.like(arcField.getFieldName(), val);
                    break;
                case "Long":
                    if (!"categoryId".equals(arcField.getFieldName())) {//categoryId 默认添加，此处排除
                        criteriaQuery.eq(arcField.getFieldName(), Long.parseLong(val));
                    }
                    break;
                default:
                    break;
            }
        } else {
            //扩展字段
            if (arcField.getDataType().intValue() == 2) {//数字
                //"json_extract(expand,\"$." + obj.getFieldName() + "\")"
                criteriaQuery.eq(getExpandColumn(arcField.getFieldName()), val);
            } else {//文本
                if (isLike) {
                    criteriaQuery.like(getExpandColumn(arcField.getFieldName()), val);
                } else {
                    criteriaQuery.eq(getExpandColumn(arcField.getFieldName()), val);
                }

            }
        }
        Long qzId = this.arcCategoryService.getById(categoryId).getQzId();
        List<Long> unitIds = userUnitService.getLoginUserUnitIds(qzId, userId);
        if (FlymeUtils.isNotEmpty(unitIds)) {
            criteriaQuery.lambda().in(ArcInfo::getUnitId, unitIds);
        }
        return this.getOne(criteriaQuery, false);
    }

    @Override
    public ArcInfo getArcInfoByArcNoAndCateGoryId(String arcNo, Long categoryId) {
        ApiAssert.isNotEmpty("档号不能为空", arcNo);
        ApiAssert.isNotEmpty("查询档案 门类id不能为空", categoryId);
        CriteriaQuery<ArcInfo> criteriaQuery = new CriteriaQuery<ArcInfo>(ArcInfo.class);
        criteriaQuery.lambda().eq(ArcInfo::getArcNo, arcNo)
                .eq(ArcInfo::getCategoryId, categoryId).eq(ArcInfo::getIsRecycle, ArchiveEnumInteger.IS_FALSE);
        return this.getOne(criteriaQuery, false);
    }

    @Override
    public ArcInfo getArcInfo(Long arcInfoId, Long categoryId) {
        ApiAssert.isNotEmpty("档案id不能为空", arcInfoId);
        ApiAssert.isNotEmpty("查询档案 门类id不能为空", categoryId);
        CriteriaQuery<ArcInfo> criteriaQuery = new CriteriaQuery<ArcInfo>(ArcInfo.class);
        criteriaQuery.lambda().eq(ArcInfo::getArcInfoId, arcInfoId)
                .eq(ArcInfo::getCategoryId, categoryId);
        return this.getOne(criteriaQuery);
    }


    @Override
    public ResultBody batchUpdate(Map param) {
        Object categoryId = param.get("categoryId");
        Object arcInfoIds = param.get("arcInfoIds");
        Object type = param.get("type");//1更新 2 替换
        Object fieldId = param.get("fieldId");
        Object replaceFrom = param.get("replaceFrom");
        Object replaceTo = param.get("replaceTo");
        ApiAssert.isNotEmpty("门类id不能为空", categoryId);
        ApiAssert.isNotEmpty("档案id不能为空", arcInfoIds);
        ApiAssert.isNotEmpty("修改方式不能为空", type);
        ApiAssert.isNotEmpty("修改字段不能为空", fieldId);
        ApiAssert.isNotEmpty("修改值不能为空", replaceTo);
        if ("2".equals(type.toString())) {
            ApiAssert.isNotEmpty("查找内容不能为空", replaceFrom);
        }
        String[] arcInfoIdsArr = arcInfoIds.toString().split(",");
        if (arcInfoIdsArr.length == 0) {
            ApiAssert.failure("档案id不能为空");
        }
        List<Long> arcInfoIdList = Arrays.asList(arcInfoIdsArr).stream().map(item -> {
            return Long.parseLong(item);
        }).collect(Collectors.toList());
        CriteriaQuery<ArcInfo> criteriaQuery = new CriteriaQuery<ArcInfo>(ArcInfo.class);
        criteriaQuery.lambda().in(ArcInfo::getArcInfoId, arcInfoIdList)
                .eq(ArcInfo::getCategoryId, Long.parseLong(categoryId.toString()));
        List<ArcInfo> list = this.list(criteriaQuery);
        ApiAssert.isNotEmpty("修改档案不能为空", list);
        ArcField field = this.arcFieldService.getById(Long.parseLong(fieldId.toString()));
        ApiAssert.isNotEmpty("修改字段不能为空", field);
        list.forEach(item -> {
            UpdateWrapper<ArcInfo> updateWrapper = new UpdateWrapper<ArcInfo>();
            updateWrapper.lambda().eq(ArcInfo::getArcInfoId, item.getArcInfoId())
                    .eq(ArcInfo::getCategoryId, item.getCategoryId());
            ArcInfo updateObj = new ArcInfo();
            if (ArchiveEnumInteger.IS_TRUE.getCode().equals(field.getIsBlob())) {
                String expand = item.getExpand();
                Map<String, Object> expandMap = null;
                if (FlymeUtils.isEmpty(expand)) {
                    expandMap = new HashMap<>();
                } else {
                    expandMap = JsonUtils.jsonToBean(expand, Map.class);
                }
                if ("1".equals(type.toString())) {
                    expandMap.put(field.getFieldName(), field.getDataType().intValue() == 1 ? replaceTo.toString() : Integer.parseInt(replaceTo.toString()));
                    updateObj.setExpand(JsonUtils.beanToJson(expandMap));
                    update(updateObj, updateWrapper);
                } else {
                    Object beforeValue = expandMap.get(field.getFieldName());
                    if (FlymeUtils.isNotEmpty(beforeValue)) {
                        expandMap.put(field.getFieldName(), field.getDataType().intValue() == 1 ? replaceTo.toString() : Integer.parseInt(replaceTo.toString()));
                        if (1 == field.getDataType().intValue()) {//值类型1字符串2数字
                            expandMap.put(field.getFieldName(), beforeValue.toString().replaceAll(replaceFrom.toString(), replaceTo.toString()));
                        } else {
                            expandMap.put(field.getFieldName(), Integer.parseInt(replaceTo.toString()));
                        }
                        updateObj.setExpand(JsonUtils.beanToJson(expandMap));
                        update(updateObj, updateWrapper);
                    }
                }
            } else {
                //    调换部门更新数量
                if ("unitId".equals(field.getFieldName())) {
                    //更新单位数据
                    if (!item.getUnitId().equals(Long.valueOf(replaceTo.toString()))) {
                        SysDept sysDept = sysDeptService.getById(replaceTo.toString());
                        sysDeptService.update(new UpdateWrapper<SysDept>().lambda().eq(SysDept::getDeptId, sysDept.getDeptId()).set(SysDept::getArcInfoCount, sysDept.getArcInfoCount() + 1));

                        SysDept sysDeptOld = sysDeptService.getById(item.getUnitId());
                        sysDeptService.update(new UpdateWrapper<SysDept>().lambda().eq(SysDept::getDeptId, sysDeptOld.getDeptId()).set(SysDept::getArcInfoCount, sysDeptOld.getArcInfoCount() - 1));
                    }

                }

                //如果字段是实体类，则根据实体类类型进行转换
                Field[] declaredFields = ArcInfo.class.getDeclaredFields();
                Map<String, Field> declaredFieldMap = Arrays.stream(declaredFields).collect(Collectors.toMap(Field::getName, Field -> Field));
                String fieldType = null;
                if (declaredFieldMap.containsKey(field.getFieldName())) {
                    fieldType = declaredFieldMap.get(field.getFieldName()).getType().getSimpleName();
                }
                if (FlymeUtils.isEmpty(fieldType)) {
                    fieldType = field.getDataType().intValue() == 1 ? "String" : "Integer";
                }
                if ("1".equals(type.toString())) {
                    //更新
                    ReflectionUtils.setFieldValue(updateObj, field.getFieldName()
                            , changeFieldValueType(fieldType, replaceTo));
                    update(updateObj, updateWrapper);
                } else {
                    Object beforeValue = ReflectionUtils.getFieldValue(item, field.getFieldName());
                    if (FlymeUtils.isNotEmpty(beforeValue)) {
                        if (field.getDataType().equals(1)) {//值类型1字符串2数字
                            ReflectionUtils.setFieldValue(updateObj, field.getFieldName()
                                    , beforeValue.toString().replaceAll(replaceFrom.toString(), replaceTo.toString()));
                        } else {
                            ReflectionUtils.setFieldValue(updateObj, field.getFieldName()
                                    , changeFieldValueType(fieldType, replaceTo));
                        }
                        //替换
                        update(updateObj, updateWrapper);
                    }
                }


            }
        });

        return ResultBody.ok();
    }

    @Override
    public Object changeFieldValueType(String type, Object value) {
        if (FlymeUtils.isEmpty(value)) {
            return "";
        }
        type = FlymeUtils.isEmpty(type) ? "Integer" : type;
        switch (type) {
            case "Integer":
                return Integer.parseInt(value.toString());
            case "String":
                return value.toString();
            case "Long":
                return Long.parseLong(value.toString());
            default:
                break;
        }
        return value;
    }

    @Override
    public String getFieldType(Field field, String defaultType) {
        if (FlymeUtils.isEmpty(field)) {
            return defaultType;
        }
        return field.getType().getSimpleName();
    }

    @Override
    public ResultBody removeCompilation(String arcInfoIds, Long categoryId) {
        String[] arcInfoIdArr = arcInfoIds.split(",");
        UpdateWrapper<ArcInfo> updateWrapper = new UpdateWrapper();
        List<Long> arcInfoIdList = Arrays.stream(arcInfoIdArr).map(item -> {
            return Long.parseLong(item);
        }).collect(Collectors.toList());
        updateWrapper.lambda().eq(ArcInfo::getCategoryId, categoryId)
                .in(ArcInfo::getArcInfoId, arcInfoIdList)
                .set(ArcInfo::getIsCompilation, ArchiveEnumInteger.IS_FALSE.getCode())
                .set(ArcInfo::getCompilationName, null);
        this.update(updateWrapper);
        this.arcCompilationRefService.removeCompilation(arcInfoIdList);
        return ResultBody.ok();
    }

    @Override
//    @Transactional(propagation=Propagation.REQUIRES_NEW)
    public boolean updateOriginalCount(String categoryId, String arcInfoId, Integer count) {
//        ArcInfo arcInfo = this.getArcInfo(Long.parseLong(arcInfoId),Long.parseLong(categoryId));
        CriteriaUpdate cu = new CriteriaUpdate();
        cu.setSql("originalCount=IFNULL(originalCount,0)+" + count); //(count<0?0:count)
//        cu.set("originalCount",FlymeUtils.isEmpty(arcInfo.getOriginalCount())?0:arcInfo.getOriginalCount());
        cu.eq(true, "arcInfoId", Long.parseLong(arcInfoId));
        cu.eq(true, "categoryId", Long.parseLong(categoryId));
        Boolean tag = update(cu);
        //更新销毁库/待借库原文数量
        updateArcUseOriginalCount(categoryId, arcInfoId);
        updateArcDestoryOriginalCount(categoryId, arcInfoId);
        return tag;
    }

    @Override
    public boolean updateCommentCount(Long categoryId, Long arcInfoId, Long count) {
        CriteriaUpdate cu = new CriteriaUpdate();
        cu.set("commentCount", count);
        cu.eq(true, "arcInfoId", arcInfoId);
        cu.eq(true, "categoryId", categoryId);
        Boolean tag = update(cu);
        return tag;
    }

    private void updateArcUseOriginalCount(String categoryId, String arcInfoId) {
        LambdaQueryWrapper<ArcUse> arcUseQueryWrapper = new LambdaQueryWrapper<>();
        arcUseQueryWrapper.eq(ArcUse::getArcInfoId, Long.parseLong(arcInfoId));
        List<ArcUse> arcUses = this.arcUseService.list(arcUseQueryWrapper);
        if (FlymeUtils.isNotEmpty(arcUses)) {
            ArcInfo arcInfo = this.getArcInfo(Long.parseLong(arcInfoId), Long.parseLong(categoryId));
            for (int i = 0; i < arcUses.size(); i++) {
                ArcUse use = arcUses.get(i);
                use.setArcNo(arcInfo.getArcNo());
                use.setOriginalCount(arcInfo.getOriginalCount());
                use.setArchiveName(arcInfo.getMaintitle());
                this.arcUseService.updateById(use);
            }
        }
    }

    private void updateArcDestoryOriginalCount(String categoryId, String arcInfoId) {
        LambdaQueryWrapper<ArcDestory> arcDestoryQueryWrapper = new LambdaQueryWrapper<>();
        arcDestoryQueryWrapper.eq(ArcDestory::getArcInfoId, Long.parseLong(arcInfoId));
        List<ArcDestory> arcDestories = this.arcDestoryService.list(arcDestoryQueryWrapper);
        if (FlymeUtils.isNotEmpty(arcDestories)) {
            ArcInfo arcInfo = this.getArcInfo(Long.parseLong(arcInfoId), Long.parseLong(categoryId));
            for (int i = 0; i < arcDestories.size(); i++) {
                ArcDestory destory = arcDestories.get(i);
                destory.setArcNo(arcInfo.getArcNo());
                destory.setOriginalCount(arcInfo.getOriginalCount());
                destory.setMaintitle(arcInfo.getMaintitle());
                this.arcDestoryService.updateById(destory);
            }
        }
    }

    @Override
    public boolean updateOriginalCount(String categoryId, String arcInfoId) {
        CriteriaUpdate cu = new CriteriaUpdate();
        cu.setSql("originalCount=0");
        cu.eq(true, "arcInfoId", Long.parseLong(arcInfoId));
        cu.eq(true, "categoryId", Long.parseLong(categoryId));
        Boolean tag = update(cu);
        //更新销毁库/待借库原文数量
        updateArcUseOriginalCount(categoryId, arcInfoId);
        updateArcDestoryOriginalCount(categoryId, arcInfoId);
        return tag;
    }

    @Override
    public ResultBody destoryBack(Map param) {
        Object destoryIds = param.get("destoryIds");
        ApiAssert.isNotEmpty("销毁库对象不能为空", destoryIds);
        List<Long> destoryIdArr = Arrays.asList(destoryIds.toString().split(",")).stream().map(item -> {
            return Long.parseLong(item);
        }).collect(Collectors.toList());
        LambdaQueryWrapper<ArcDestory> lambdaQueryWrapper = new LambdaQueryWrapper<ArcDestory>();
        lambdaQueryWrapper.in(ArcDestory::getDestoryId, destoryIdArr);
        List<ArcDestory> list = this.arcDestoryService.list(lambdaQueryWrapper);
        ApiAssert.isNotEmpty("销毁库对象不能为空", list);
        list.forEach(item -> {
            if (!item.getStatus().equals(ArcDestoryStatusEnum.ARC_STATUS_1.getCode())) {
                ApiAssert.failure("只有待销毁文件库可以还原");
            }
            LambdaUpdateWrapper<ArcInfo> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            lambdaUpdateWrapper.eq(ArcInfo::getCategoryId, item.getCategoryId())
                    .eq(ArcInfo::getArcInfoId, item.getArcInfoId())
                    .set(ArcInfo::getIsDestory, ArchiveEnumInteger.IS_FALSE.getCode());
            this.update(lambdaUpdateWrapper);

            LambdaUpdateWrapper<ArcDestory> lambdaDestoryUpdateWrapper = new LambdaUpdateWrapper<>();
            lambdaDestoryUpdateWrapper.eq(ArcDestory::getDestoryId, item.getDestoryId())
                    .set(ArcDestory::getStatus, ArcDestoryStatusEnum.ARC_STATUS_0.getCode());
            this.arcDestoryService.update(lambdaDestoryUpdateWrapper);
        });

        return ResultBody.ok();
    }

    @Override
    public ResultBody batchInOrOut(Map param) {
        Object parentArcInfoId = param.get("parentArcInfoId");
        Object parentCategoryId = param.get("parentCategoryId");
        Object type = param.get("type");//1调入 2调出
        Object childCategoryId = param.get("childCategoryId");
        Object childArcInfoIds = param.get("childArcInfoIds");
        ApiAssert.isNotEmpty("父档案id不能为空", parentArcInfoId);
        ApiAssert.isNotEmpty("父门类id不能为空", parentCategoryId);
        ApiAssert.isNotEmpty("类型不能为空", type);
        ApiAssert.isNotEmpty("子门类id不能为空", childCategoryId);
        ApiAssert.isNotEmpty("子档案id不能为空", childArcInfoIds);
        ArcInfo parentArcInfo = this.getArcInfo(Long.parseLong(parentArcInfoId.toString()), Long.parseLong(parentCategoryId.toString()));
        ApiAssert.isNotEmpty("父档案不能为空", parentArcInfo);

        //更新父档案
        LambdaUpdateWrapper<ArcInfo> parentArcInfoUpdate = new LambdaUpdateWrapper<>();
        parentArcInfoUpdate.eq(ArcInfo::getArcInfoId, Long.parseLong(parentArcInfoId.toString()))
                .eq(ArcInfo::getCategoryId, Long.parseLong(parentCategoryId.toString()));
        Integer childCount = parentArcInfo.getChildCount() == null ? 0 : parentArcInfo.getChildCount();

        //更新子档案
        String[] childArcInfoIdsArr = childArcInfoIds.toString().split(",");
        LambdaUpdateWrapper<ArcInfo> childArcInfoUpdate = new LambdaUpdateWrapper<>();
        childArcInfoUpdate.eq(ArcInfo::getCategoryId, Long.parseLong(childCategoryId.toString()))
                .in(ArcInfo::getArcInfoId, Arrays.stream(childArcInfoIdsArr).map(item -> {
                    return Long.parseLong(item);
                }).collect(Collectors.toList()));
        if ("1".equals(type.toString())) {//调入
            //更新父档案
            parentArcInfoUpdate.set(ArcInfo::getChildCount, childCount + childArcInfoIdsArr.length);
            this.update(parentArcInfoUpdate);
            //更新子档案
            childArcInfoUpdate.set(ArcInfo::getParentId, Long.parseLong(parentArcInfoId.toString()));
            this.update(childArcInfoUpdate);
        } else {
            //更新父档案
            parentArcInfoUpdate.set(ArcInfo::getChildCount,
                    childCount > childArcInfoIdsArr.length ? childCount - childArcInfoIdsArr.length : 0);
            this.update(parentArcInfoUpdate);
            //更新子档案
            childArcInfoUpdate.set(ArcInfo::getParentId, null);
            this.update(childArcInfoUpdate);
        }
        return ResultBody.ok();
    }

    @Override
    public ResultBody batchUpdateArcNo(Map param) {
        Object categoryId = param.get("categoryId");
        Object arcInfoIds = param.get("arcInfoIds");
        Object arcNos = param.get("arcNos");
        ApiAssert.isNotEmpty("门类id不能为空", categoryId);
        ApiAssert.isNotEmpty("档案id不能为空", arcInfoIds);
        ApiAssert.isNotEmpty("档号不能为空", arcNos);
        String[] arcInfoIdArr = arcInfoIds.toString().split(",");
        List<String> arcNoList = JsonUtils.json2list(arcNos.toString(), String.class);
        if (arcInfoIdArr.length != arcNoList.size()) {
            ApiAssert.failure("档号id与档号数量不一致");
        }
        for (int i = 0; i < arcInfoIdArr.length; i++) {
            LambdaUpdateWrapper<ArcInfo> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            lambdaUpdateWrapper.eq(ArcInfo::getCategoryId, Long.parseLong(categoryId.toString()))
                    .eq(ArcInfo::getArcInfoId, Long.parseLong(arcInfoIdArr[i])).set(ArcInfo::getArcNo, arcNoList.get(i));
            update(lambdaUpdateWrapper);

        }
        return ResultBody.ok();
    }

    @Override
    public ResultBody genPieceNo(Map param) {
        Object categoryId = param.get("categoryId");
        Object arcInfoIds = param.get("arcInfoIds");
        Object value = param.get("value");
        ApiAssert.isNotEmpty("门类id不能为空", categoryId);
        ApiAssert.isNotEmpty("档案id不能为空", arcInfoIds);
        ApiAssert.isNotEmpty("件号不能为空", value);
        if (!NumberUtil.isNumber(value.toString())) {
            ApiAssert.failure("件号必须为数字");
        }
        ;
        String[] arcInfoIdsArr = arcInfoIds.toString().split(",");
        if (arcInfoIdsArr.length == 0) {
            ApiAssert.failure("档案id不能为空");
        }
        //查询门类 件号对应的自动补零策略
        QueryWrapper<ArcField> fieldQueryWrapper = new QueryWrapper<>();
        fieldQueryWrapper.lambda().eq(ArcField::getCategoryId, Long.parseLong(categoryId.toString()))
                .eq(ArcField::getFieldName, "pieceNo");
        List<ArcField> list = this.arcFieldService.list(fieldQueryWrapper);
        ApiAssert.isNotEmpty("该门类查询不到件号字段", list);
        if (list.size() > 1) {
            ApiAssert.failure("该门类查询到多个件号");
        }
        ArcField field = list.get(0);
        boolean isAutoZero = false;//是否自动补0
        Integer inZeroNum = null;//自动补0位数
        if (ArchiveEnumInteger.IS_TRUE.getCode().equals(field.getInAutoZero())) {
            inZeroNum = field.getInZeroNum();
            if (FlymeUtils.isEmpty(inZeroNum) || inZeroNum == 0) {
                ApiAssert.failure("该门类件号开启自动补零但是没配置位数");
            }
            isAutoZero = true;
        }
        for (int i = 0; i < arcInfoIdsArr.length; i++) {
            ArcInfo obj = this.getArcInfo(Long.parseLong(arcInfoIdsArr[i]), Long.parseLong(categoryId.toString()));
            ApiAssert.isNotEmpty("档案id与门类id不匹配", obj);
            UpdateWrapper<ArcInfo> updateWrapper = new UpdateWrapper<>();
            updateWrapper.lambda().eq(ArcInfo::getCategoryId, Long.parseLong(categoryId.toString()))
                    .eq(ArcInfo::getArcInfoId, obj.getArcInfoId());
            if (isAutoZero) {
                //设置件号
                updateWrapper.lambda().set(ArcInfo::getPieceNo,
                        ArcUtils.numberFormatStr(inZeroNum, NumberUtil.parseInt(value.toString()) + i));
            } else {
                //设置件号
                updateWrapper.lambda().set(ArcInfo::getPieceNo,
                        ArcUtils.numberFormatStr(1, NumberUtil.parseInt(value.toString()) + i));
            }
            this.update(updateWrapper);
        }
        return ResultBody.ok();
    }

    //TODO 分片注意  此处涉及两个门类之间进行操作
    private void srcArcInfo2TargetArcInfo(List<Long> arcInfoIds, ArcConfig arcConfig, Map<String, Object> arcParam, List<ArcNumFmt> arcNumFmts) {
        //1  归档配置详情信息
        CriteriaQuery<ArcConfigRef> refCriteriaQuery = new CriteriaQuery<ArcConfigRef>(ArcConfigRef.class);
        refCriteriaQuery.lambda().eq(ArcConfigRef::getConfigId, arcConfig.getConfigId());
        List<ArcConfigRef> configRefs = this.arcConfigRefService.list(refCriteriaQuery);
        if (FlymeUtils.isEmpty(configRefs)) {
            ApiAssert.failure("归档配置没有详情信息，无法归档");
        }
        List<Long> srcConfigRefFields = new ArrayList<>();
        List<Long> targetConfigRefFields = new ArrayList<>();
        configRefs.forEach(item -> {
            ApiAssert.isNotEmpty("归档配置源门类字段不能为空", item.getSrcFieldId());
            ApiAssert.isNotEmpty("归档配置目标门类字段不能为空", item.getTargetFieldId());
            srcConfigRefFields.add(item.getSrcFieldId());
            targetConfigRefFields.add(item.getTargetFieldId());
        });

        //2  源档案信息
        CriteriaQuery<ArcInfo> arcInfoCriteriaQuery = new CriteriaQuery<ArcInfo>(ArcInfo.class);
        arcInfoCriteriaQuery.lambda().in(ArcInfo::getArcInfoId, arcInfoIds)
                .eq(ArcInfo::getCategoryId, arcConfig.getSrcCategoryId());
        List<ArcInfo> srcArcInfo = this.list(arcInfoCriteriaQuery);
        if (FlymeUtils.isEmpty(srcArcInfo)) {
            ApiAssert.failure("没有要归档的文件，无法归档");
        }
        Long count = srcArcInfo.stream().filter(item -> {
            return ArcStatusEnum.ARC_STATUS_1.getCode().equals(item.getStatus());
        }).count();
        if (srcArcInfo.size() - count > 0) {
            ApiAssert.failure("部分档案没有加入待归档，无法归档");
        }


        //3  校验源门类字段列表与目标门类字段列表
        CriteriaQuery<ArcField> arcFieldCriteriaQuery = new CriteriaQuery<ArcField>(ArcField.class);
        arcFieldCriteriaQuery.lambda().in(ArcField::getCategoryId, arcConfig.getSrcCategoryId(), arcConfig.getTargetCategoryId());
        List<ArcField> arcFields = arcFieldService.list(arcFieldCriteriaQuery);
        Map<Long, ArcField> transArcFields = arcFields.stream().filter(item -> {
            return srcConfigRefFields.contains(item.getFieldId()) || targetConfigRefFields.contains(item.getFieldId());
        }).collect(Collectors.toMap(ArcField::getFieldId, ArcField -> ArcField));

        Map<Long, ArcField> targetArcFields = arcFields.stream().filter(item -> {
            return item.getCategoryId().equals(arcConfig.getTargetCategoryId());
        }).collect(Collectors.toMap(ArcField::getFieldId, ArcField -> ArcField));

        ApiAssert.isNotEmpty("基于归档配置查询门类字段为空", transArcFields);
        if ((transArcFields.keySet().size() - configRefs.size() * 2) != 0) {
            ApiAssert.failure("归档配置对应源档案字段与目标档案数量不一致，可能字段已删除");
        }
        //目标门类档号字段
        Map<String, ArcField> arcNumFieldMap = arcFields.stream().filter(item -> {
            return item.getCategoryId().equals(arcConfig.getTargetCategoryId()) && item.getIsArcNum().equals(ArchiveEnumInteger.IS_TRUE.getCode());
        }).collect(Collectors.toMap(ArcField::getFieldName, ArcField -> ArcField));


        //4 基于源档案  根据归档配置 生成目标档案
        List<ArcInfo> targetArcInfos = new ArrayList<ArcInfo>();
        ForEachIndex indexObj = new ForEachIndex();
        srcArcInfo.forEach(arcInfo -> {
            indexObj.indexPlus();
            ArcInfo targetArcInfo = new ArcInfo();
            //档案id不变更，不然档案原文关联关系小时
            targetArcInfo.setArcInfoId(arcInfo.getArcInfoId());
            config:
            for (int i = 0; i < configRefs.size(); i++) {
                ArcConfigRef configRef = configRefs.get(i);
                ArcField srcField = transArcFields.get(configRef.getSrcFieldId());
                ArcField targetField = transArcFields.get(configRef.getTargetFieldId());
                if (ArchiveEnumInteger.IS_TRUE.getCode().equals(srcField.getIsBlob())) {
                    if (FlymeUtils.isEmpty(arcInfo.getExpand())) {
                        continue config;
                    }
                    Map<String, Object> srcExpand = JsonUtils.jsonToBean(arcInfo.getExpand(), Map.class);
                    if (FlymeUtils.isEmpty(srcExpand.get(srcField.getFieldName()))) {
                        continue config;
                    }
                    if (ArchiveEnumInteger.IS_TRUE.getCode().equals(targetField.getIsBlob())) {
                        Map<String, Object> targetExpand = FlymeUtils.isEmpty(targetArcInfo.getExpand()) ? new HashMap<>() : JsonUtils.jsonToBean(targetArcInfo.getExpand(), Map.class);
                        targetExpand.put(targetField.getFieldName(), srcExpand.get(srcField.getFieldName()) == null ? "" : srcExpand.get(srcField.getFieldName()).toString());
                        targetArcInfo.setExpand(JsonUtils.beanToJson(targetExpand));
                    } else {
                        Field[] declaredFields = ArcInfo.class.getDeclaredFields();
                        Map<String, Field> declaredFieldMap = Arrays.stream(declaredFields).collect(Collectors.toMap(Field::getName, Field -> Field));
                        String fieldType = null;
                        if (declaredFieldMap.containsKey(targetField.getFieldName())) {
                            fieldType = declaredFieldMap.get(targetField.getFieldName()).getType().getSimpleName();
                        }
                        if (FlymeUtils.isEmpty(fieldType)) {
                            fieldType = targetField.getDataType().intValue() == 1 ? "String" : "Integer";
                        }
                        try {
                            ReflectionUtils.setFieldValue(targetArcInfo, targetField.getFieldName()
                                    , this.changeFieldValueType(fieldType, srcExpand.get(srcField.getFieldName())));
                        } catch (Exception e) {
                            log.error(String.format("档案归档值类型转换错误 源门类id=%s,目标门类id=%s,源档案id=%s" +
                                            ",源字段id=%s,目标字段id=%s,源字段名称=%s,目标字段名称=%s, 源字段值=%s ",
                                    srcField.getCategoryId(), targetField.getCategoryId(), arcInfo.getArcInfoId(),
                                    srcField.getFieldId(), targetField.getFieldId(), srcField.getFieldName(), targetField.getFieldName(),
                                    srcExpand.get(srcField.getFieldName())), e);
                            ApiAssert.failure("档案归档数据映射类型不正确，请检查数据类型");
                        }
                        //值类型1字符串2数字
//                        if(1==targetField.getDataType()){
//                            ReflectionUtils.setFieldValue(targetArcInfo,targetField.getFieldName()
//                                    ,srcExpand.get(srcField.getFieldName()).toString());
//                        }else{
//                            try{
//                                ReflectionUtils.setFieldValue(targetArcInfo,targetField.getFieldName()
//                                        ,Integer.parseInt(srcExpand.get(srcField.getFieldName()).toString()));
//                            }catch (Exception e){
//                                log.error(String.format("档案归档值类型转换错误 源门类id=%s,目标门类id=%s,源档案id=%s" +
//                                        ",源字段id=%s,目标字段id=%s,源字段名称=%s,目标字段名称=%s, 源字段值=%s ",
//                                        srcField.getCategoryId(),targetField.getCategoryId(),arcInfo.getArcInfoId(),
//                                        srcField.getFieldId(),targetField.getFieldId(),srcField.getFieldName(),targetField.getFieldName(),
//                                        srcExpand.get(srcField.getFieldName())),e);
//                                ApiAssert.failure("档案归档数据映射类型不正确，请检查数据类型");
//                            }
//
//                        }
                    }
                } else {

                    Object srcValue = ReflectionUtils.getFieldValue(arcInfo, srcField.getFieldName());
                    if (FlymeUtils.isEmpty(srcValue)) {
                        continue config;
                    }
                    if (ArchiveEnumInteger.IS_TRUE.getCode().equals(targetField.getIsBlob())) {
                        Map<String, Object> targetExpand = FlymeUtils.isEmpty(targetArcInfo.getExpand()) ? new HashMap<>() : JsonUtils.jsonToBean(targetArcInfo.getExpand(), Map.class);
                        targetExpand.put(targetField.getFieldName(), srcValue);
                        targetArcInfo.setExpand(JsonUtils.beanToJson(targetExpand));
                    } else {
                        Field[] declaredFields = ArcInfo.class.getDeclaredFields();
                        Map<String, Field> declaredFieldMap = Arrays.stream(declaredFields).collect(Collectors.toMap(Field::getName, Field -> Field));
                        String fieldType = null;
                        if (declaredFieldMap.containsKey(targetField.getFieldName())) {
                            fieldType = declaredFieldMap.get(targetField.getFieldName()).getType().getSimpleName();
                        }
                        if (FlymeUtils.isEmpty(fieldType)) {
                            fieldType = targetField.getDataType().intValue() == 1 ? "String" : "Integer";
                        }
                        try {
                            ReflectionUtils.setFieldValue(targetArcInfo, targetField.getFieldName()
                                    , this.changeFieldValueType(fieldType, srcValue));
                        } catch (Exception e) {
                            log.error(String.format("档案归档值类型转换错误 源门类id=%s,目标门类id=%s,源档案id=%s" +
                                            ",源字段id=%s,目标字段id=%s,源字段名称=%s,目标字段名称=%s, 源字段值=%s ",
                                    srcField.getCategoryId(), targetField.getCategoryId(), arcInfo.getArcInfoId(),
                                    srcField.getFieldId(), targetField.getFieldId(), srcField.getFieldName(), targetField.getFieldName(),
                                    srcValue), e);
                            ApiAssert.failure("档案归档数据映射类型不正确，请检查数据类型");
                        }
                        //值类型1字符串2数字
//                        if(1==targetField.getDataType()){
//                            ReflectionUtils.setFieldValue(targetArcInfo,targetField.getFieldName()
//                                    ,srcValue.toString());
//                        }else{
//                            try{
//                                ReflectionUtils.setFieldValue(targetArcInfo,targetField.getFieldName()
//                                        ,Integer.parseInt(srcValue.toString()));
//                            }catch (Exception e){
//                                log.error(String.format("档案归档值类型转换错误 源门类id=%s,目标门类id=%s,源档案id=%s" +
//                                                ",源字段id=%s,目标字段id=%s,源字段名称=%s,目标字段名称=%s, 源字段值=%s ",
//                                        srcField.getCategoryId(),targetField.getCategoryId(),arcInfo.getArcInfoId(),
//                                        srcField.getFieldId(),targetField.getFieldId(),srcField.getFieldName(),targetField.getFieldName(),
//                                        srcValue),e);
//                                ApiAssert.failure("档案归档数据映射类型不正确，请检查数据类型");
//                            }
//
//                        }
                    }
                }

            }
            //4 归档  档号字段与两个自定义字段值处理
            arcParam.forEach((key, value) -> {
                if (FlymeUtils.isNotEmpty(value)) {
                    ArcField field = targetArcFields.get(Long.parseLong(key.toString()));
                    if (FlymeUtils.isNotEmpty(field) && arcConfig.getTargetCategoryId().equals(field.getCategoryId())) {
                        if (ArchiveEnumInteger.IS_TRUE.getCode().equals(field.getIsBlob())) {
                            Map<String, Object> targetExpand = FlymeUtils.isEmpty(targetArcInfo.getExpand()) ? new HashMap<>() : JsonUtils.jsonToBean(targetArcInfo.getExpand(), Map.class);
                            targetExpand.put(field.getFieldName(), value.toString());
                            targetArcInfo.setExpand(JsonUtils.beanToJson(targetExpand));
                        } else {
                            Field[] declaredFields = ArcInfo.class.getDeclaredFields();
                            Map<String, Field> declaredFieldMap = Arrays.stream(declaredFields).collect(Collectors.toMap(Field::getName, Field -> Field));
                            String fieldType = null;
                            if (declaredFieldMap.containsKey(field.getFieldName())) {
                                fieldType = declaredFieldMap.get(field.getFieldName()).getType().getSimpleName();
                            }
                            if (FlymeUtils.isEmpty(fieldType)) {
                                fieldType = field.getDataType().intValue() == 1 ? "String" : "Integer";
                            }
                            try {
                                ReflectionUtils.setFieldValue(targetArcInfo, field.getFieldName()
                                        , this.changeFieldValueType(fieldType, value));
                            } catch (Exception e) {
                                log.error(String.format("归档信息值类型转换错误 目标门类id=%s,源档案id=%s" +
                                                ",目标字段id=%s,目标字段名称=%s, 目标字段值=%s ",
                                        field.getCategoryId(), arcInfo.getArcInfoId(),
                                        field.getFieldId(), field.getFieldName(), value), e);
                                ApiAssert.failure("归档信息值类型转换错误，请检查数据类型");
                            }


//                            //值类型1字符串2数字
//                            if(1==field.getDataType()){
//                                ReflectionUtils.setFieldValue(targetArcInfo,field.getFieldName()
//                                        ,value.toString());
//                            }else{
//                                try{
//                                    ReflectionUtils.setFieldValue(targetArcInfo,field.getFieldName()
//                                            ,Integer.parseInt(value.toString()));
//                                }catch (Exception e){
//                                    log.error(String.format("归档信息值类型转换错误 目标门类id=%s,源档案id=%s" +
//                                                    ",目标字段id=%s,目标字段名称=%s, 目标字段值=%s ",
//                                            field.getCategoryId(),arcInfo.getArcInfoId(),
//                                            field.getFieldId(),field.getFieldName(), value),e);
//                                    ApiAssert.failure("归档信息值类型转换错误，请检查数据类型");
//                                }
//
//                            }
                        }
                    }
                }
            });
            //5 档号处理
            StringBuffer arcNumSb = new StringBuffer();
            arcNumFmts.forEach(item -> {
                ArcField arcNumField = arcNumFieldMap.get(item.getFieldName());
                //件号特殊处理
                if (item.getFieldName().equals("pieceNo")) {
                    arcNumSb.append(arcInfo.getPieceNo());
                    targetArcInfo.setPieceNo(arcInfo.getPieceNo());
                } else if (item.getFieldName().equals("unitId")) {
                    SysDept sysDept = sysDeptService.getById(Long.valueOf(arcParam.get(arcNumField.getFieldId().toString()).toString()));
                    arcNumSb.append(sysDept.getDeptCode());
                } else {
                    arcNumSb.append(arcParam.get(arcNumField.getFieldId().toString()));
                }
                arcNumSb.append(item.getArcConnect());
                //将档号字段相应的配置信息都覆盖到
            });
            targetArcInfo.setArcNo(arcNumSb.toString());

            targetArcInfo.setCategoryId(arcConfig.getTargetCategoryId());
            targetArcInfo.setQzId(arcInfo.getQzId());
            targetArcInfo.setOriginalCount(arcInfo.getOriginalCount());
            initArcInfoPreField(targetArcInfo);
            targetArcInfos.add(targetArcInfo);
        });

        //6 删除源门类数据 添加目标门类数据
        CriteriaDelete<ArcInfo> criteriaDelete = new CriteriaDelete<ArcInfo>();
        criteriaDelete.lambda().eq(ArcInfo::getCategoryId, arcConfig.getSrcCategoryId())
                .in(ArcInfo::getArcInfoId, arcInfoIds);
        this.remove(criteriaDelete);
        this.saveBatch(targetArcInfos);
    }

    //档案管理字段初始化
    //档案管理导入初始化
    @Override
    public void initArcInfoPreField(ArcInfo arcInfo) {
        if (FlymeUtils.isNotEmpty(arcInfo)) {
            arcInfo.setIsUse(ArchiveEnumInteger.IS_FALSE.getCode());
            arcInfo.setIsStore(ArchiveEnumInteger.IS_FALSE.getCode());
            arcInfo.setIsRecycle(ArchiveEnumInteger.IS_FALSE.getCode());
            arcInfo.setIsDestory(ArchiveEnumInteger.IS_FALSE.getCode());
            arcInfo.setIsCompilation(ArchiveEnumInteger.IS_FALSE.getCode());
            arcInfo.setStatus(ArcStatusEnum.ARC_STATUS_2.getCode());
        }
    }

    public static void main(String[] args) {
        Field[] declaredFields = ArcInfo.class.getDeclaredFields();
        Arrays.stream(declaredFields).forEach(item -> {
            System.out.println(item.getType().getSimpleName());
        });
        System.out.println(ArcUtils.numberFormatStr(1, 111));
        System.out.println(NumberUtil.isNumber("001"));
        System.out.println("11111111111111111111111111111");
        Map<String, Object> aaa = new HashMap<>();
        aaa.put("1", 1);
        String targetExpand = JsonUtils.beanToJson(aaa);
        String bbb = "{aaa:1,bbb:3,1:3}";
        Map<String, Object> ccc = JsonUtils.jsonToBean(bbb, Map.class);
        System.out.println(targetExpand);
        Integer a = Integer.parseInt("1");
        System.out.println(1 == a);
        System.out.println(String.format("档案归档值类型转换错误 源门类id=%s,目标门类id=%s,源档案id=%s",
                "哈哈", 1, null));
        String b = "还是说xxxdfdsf嘿说嘿";
        System.out.println(b.replaceAll("说", "哦"));
    }

    private String getExpandColumn(String column) {
        System.out.println("#######################dataSourceUrl:" + dataSourceUrl);
        //人大金仓数据源
        if (FlymeUtils.isNotEmpty(dataSourceUrl) && dataSourceUrl.indexOf("postgresql") > -1) {
            return "json_extract_path_text(expand::JSON,'" + column + "')";
            //瀚高数据源
        } else if (FlymeUtils.isNotEmpty(dataSourceUrl) && dataSourceUrl.indexOf("highgo") > -1) {
            return "json_extract_path_text(expand::JSON,'" + column + "')";
        } else {//mysql数据源
            //"json_extract(expand,\"$." + obj.getFieldName() + "\")"
            return "json_extract(expand,\"$." + column + "\")";
        }
    }

    /**
     * @param column
     * @param dataType 值类型1字符串2数字
     * @return
     */
    private String getExpandColumnWithType(String column, Integer dataType, int inType) {
        System.out.println("#*****##############dataSourceUrl:" + dataSourceUrl);

        //return getExpandColumn(column);
        //人大金仓数据源
        if (FlymeUtils.isNotEmpty(dataSourceUrl) && dataSourceUrl.indexOf("postgresql") > -1) {
            if (dataType != null && dataType.intValue() == 2) {
                return "json_extract_path_text(expand::JSON,'" + column + "')::numeric";
            } else {
                if (inType == 2) {
                    return "json_extract_path_text(expand::JSON,'" + column + "')::numeric";
                }
                return "json_extract_path_text(expand::JSON,'" + column + "')";
            }
            //瀚高数据源
        } else if (FlymeUtils.isNotEmpty(dataSourceUrl) && dataSourceUrl.indexOf("highgo") > -1) {
            if (dataType != null && dataType.intValue() == 2) {
                return "json_extract_path_text(expand::JSON,'" + column + "')::numeric";
            } else {
                if (inType == 2) {
                    return "json_extract_path_text(expand::JSON,'" + column + "')::numeric";
                }
                return "json_extract_path_text(expand::JSON,'" + column + "')";
            }
        } else {//mysql数据源
            //"json_extract(expand,\"$." + obj.getFieldName() + "\")"
            if (dataType != null && dataType.intValue() == 2) {
                return "CAST(json_extract(expand,\"$." + column + "\") AS DECIMAL)";
            } else {
                if (inType == 2) {
                    return "CAST(json_extract(expand,\"$." + column + "\") AS DECIMAL)";
                }
                return "json_extract(expand,\"$." + column + "\")";
            }
        }
    }

    private String getColumnWithType(String column, Integer dataType, int inType) {
        if (dataType != null && dataType == 2) {
            return "CAST( " + column + "  AS DECIMAL)";
        } else {
            if (inType == 2) {
                return "CAST( " + column + "  AS DECIMAL)";
            }
            return column;
        }
    }

    @Override
    public ResultBody espageList(Map params) {


        // 检查是否有索引
        Boolean original_document = arcOriginalRepository.existsIndex("original_document");
        if (!original_document) {
            return ResultBody.ok();
        }

        Object qzId = params.get("qzId");
        ApiAssert.isNotEmpty("全宗Id不能为空", qzId);
        LambdaQueryWrapper<ArcCategory> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.ne(ArcCategory::getType, CategoryTypeEnum.CATEGORY_TYPE_0.getCode())
                .likeRight(ArcCategory::getSysCode, "A02");
        //过滤用户角色权限
        lambdaQueryWrapper.inSql(ArcCategory::getCategoryId, "select cu.categoryId from arc_category_user cu " +
                "left join base_role_user ru on cu.roleId = ru.roleId where ru.userId = " + OpenHelper.getUserId());


        //根据全宗id过滤   或   类型属于系统级别
        lambdaQueryWrapper.and(wrap -> {
            wrap.eq(ArcCategory::getQzId, Long.parseLong(qzId.toString()))
                    .or().eq(ArcCategory::getIsSystem, ArchiveEnumInteger.IS_SYSTEM.getCode());
        });
        List<ArcCategory> categories = this.arcCategoryService.list(lambdaQueryWrapper);
        List<Long> collect = categories.stream().map(ArcCategory::getCategoryId).collect(Collectors.toList());
        LambdaEsQueryWrapper<ArcOriginalEs> wrapper = new LambdaEsQueryWrapper<>();
        wrapper.match(ArcOriginalEs::getFileContent, MapUtil.getStr(params, "keyword"));
        wrapper.sortByScore(SortOrder.DESC);

        wrapper.in(ArcOriginalEs::getCategoryId, collect);
        wrapper.eq(ObjectUtil.isNotNull(params.get("categoryId")), ArcOriginalEs::getCategoryId, MapUtil.getLong(params, "categoryId"));
        //List<ArcOriginalEs> documents = arcOriginalRepository.selectList(wrapper);


        EntityMap data = new EntityMap();
        data.put("records", Arrays.asList());
        data.put("current", 1);
        data.put("pages", 0);
        data.put("size", MapUtil.getInt(params, "limit"));
        data.put("total", 0);
        EsPageInfo<ArcOriginalEs> documentPageInfo = arcOriginalRepository.pageQuery(wrapper, MapUtil.getInt(params, "page"), MapUtil.getInt(params, "limit"));

        if (CollUtil.isEmpty(documentPageInfo.getList())) {
            return ResultBody.ok(data);
        }
        params.put("arcInfoIds", documentPageInfo.getList().stream().map(ArcOriginalEs::getArcInfoId).collect(Collectors.joining(",")));

        Map<String, ArcOriginalEs> esMap = documentPageInfo.getList().stream().collect(Collectors.toMap(ArcOriginalEs::getArcInfoId, ArcOriginalEs -> ArcOriginalEs, (a, b) -> a));


        ResultBody resultBody = this.listEntityMap(params);
        List<EntityMap> list = (List<EntityMap>) resultBody.getData();

        for (EntityMap arcOriginalEs : list) {
            arcOriginalEs.put("content_", esMap.get(arcOriginalEs.get("arcInfoId").toString()).getHighlightContent());
        }

        data.put("records", list);
        data.put("current", documentPageInfo.getPageNum());
        data.put("pages", documentPageInfo.getPages());
        data.put("size", documentPageInfo.getPageSize());
        data.put("total", documentPageInfo.getTotal());

        return ResultBody.ok(data);
    }


    @Override
    public ResultBody esCategoryQuery(Map param) {
        // 检查是否有索引
        Boolean original_document = arcOriginalRepository.existsIndex("original_document");
        if (!original_document) {
            return ResultBody.ok();
        }
        Object qzId = param.get("qzId");
        ApiAssert.isNotEmpty("全宗Id不能为空", qzId);
        LambdaQueryWrapper<ArcCategory> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.ne(ArcCategory::getType, CategoryTypeEnum.CATEGORY_TYPE_0.getCode())
                .likeRight(ArcCategory::getSysCode, "A02");
        //过滤用户角色权限
        lambdaQueryWrapper.inSql(ArcCategory::getCategoryId, "select cu.categoryId from arc_category_user cu " +
                "left join base_role_user ru on cu.roleId = ru.roleId where ru.userId = " + OpenHelper.getUserId());


        //根据全宗id过滤   或   类型属于系统级别
        lambdaQueryWrapper.and(wrap -> {
            wrap.eq(ArcCategory::getQzId, Long.parseLong(qzId.toString()))
                    .or().eq(ArcCategory::getIsSystem, ArchiveEnumInteger.IS_SYSTEM.getCode());
        });

        LambdaEsQueryWrapper<ArcOriginalEs> wrapper = new LambdaEsQueryWrapper<>();
        wrapper.match(ArcOriginalEs::getFileContent, MapUtil.getStr(param, "keyword"));
        List<ArcOriginalEs> documents = arcOriginalRepository.selectList(wrapper);
        if (CollUtil.isEmpty(documents)) {
            return ResultBody.ok(documents);
        }
        List<String> categoriesids = documents.stream().map(ArcOriginalEs::getCategoryId).collect(Collectors.toList());
        lambdaQueryWrapper.in(ArcCategory::getCategoryId, categoriesids);
        List<ArcCategory> categories = this.arcCategoryService.list(lambdaQueryWrapper);
        Map<Long, ArcCategory> categoryMap = categories.stream()
                .collect(Collectors.toMap(ArcCategory::getCategoryId, ArcCategory -> ArcCategory));
        List<Future<Long>> futures = new ArrayList<>();
        Long userId = OpenHelper.getUserId();
        categories.forEach(item -> {
            final Map map = new HashMap();
            map.putAll(param);
            map.put("tempUserId_", userId);
            Future<Long> future = syncService.categoryHasArcQuery(item.getCategoryId(), null, map);
            futures.add(future);
        });
        List<ArcCategory> result = new ArrayList<>();
        futures.forEach(item -> {
            try {
                Long l = item.get();
                if (!l.equals(0L)) {
                    ArcCategory category = categoryMap.get(l);
                    if (FlymeUtils.isNotEmpty(category)) {
                        result.add(category);
                    }
                }

            } catch (Exception e) {
                log.error("获取门类异常", e);
                ApiAssert.failure("获取门类异常");
            }
        });
        return ResultBody.ok(result);
    }

}
